r313666 - Teach clang to tolerate the 'p = nullptr + n' idiom used by glibc

2017-09-19 Thread Andrew Kaylor via cfe-commits
Author: akaylor
Date: Tue Sep 19 13:26:40 2017
New Revision: 313666

URL: http://llvm.org/viewvc/llvm-project?rev=313666&view=rev
Log:
Teach clang to tolerate the 'p = nullptr + n' idiom used by glibc

Differential Revision: https://reviews.llvm.org/D37042


Added:
cfe/trunk/test/CodeGen/nullptr-arithmetic.c
cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Sema/pointer-addition.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=313666&r1=313665&r2=313666&view=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Sep 19 13:26:40 2017
@@ -3126,6 +3126,12 @@ public:
 return isShiftAssignOp(getOpcode());
   }
 
+  // Return true if a binary operator using the specified opcode and operands
+  // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
+  // integer to a pointer.
+  static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
+   Expr *LHS, Expr *RHS);
+
   static bool classof(const Stmt *S) {
 return S->getStmtClass() >= firstBinaryOperatorConstant &&
S->getStmtClass() <= lastBinaryOperatorConstant;

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=313666&r1=313665&r2=313666&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Sep 19 13:26:40 2017
@@ -338,6 +338,7 @@ def NonPODVarargs : DiagGroup<"non-pod-v
 def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
 def : DiagGroup<"nonportable-cfstrings">;
 def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
+def NullPointerArithmetic : DiagGroup<"null-pointer-arithmetic">;
 def : DiagGroup<"effc++", [NonVirtualDtor]>;
 def OveralignedType : DiagGroup<"over-aligned">;
 def AlignedAllocationUnavailable : DiagGroup<"aligned-allocation-unavailable">;
@@ -706,7 +707,8 @@ def Extra : DiagGroup<"extra", [
 SemiBeforeMethodBody,
 MissingMethodReturnType,
 SignCompare,
-UnusedParameter
+UnusedParameter,
+NullPointerArithmetic
   ]>;
 
 def Most : DiagGroup<"most", [

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=313666&r1=313665&r2=313666&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 19 13:26:40 
2017
@@ -5501,6 +5501,12 @@ def err_offsetof_field_of_virtual_base :
 def warn_sub_ptr_zero_size_types : Warning<
   "subtraction of pointers to type %0 of zero size has undefined behavior">,
   InGroup;
+def warn_pointer_arith_null_ptr : Warning<
+  "performing pointer arithmetic on a null pointer has undefined 
behavior%select{| if the offset is nonzero}0">,
+  InGroup, DefaultIgnore;
+def warn_gnu_null_ptr_arith : Warning<
+  "arithmetic on a null pointer treated as a cast from integer to pointer is a 
GNU extension">,
+  InGroup, DefaultIgnore;
 
 def warn_floatingpoint_eq : Warning<
   "comparing floating point with == or != is unsafe">,

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=313666&r1=313665&r2=313666&view=diff
==
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Sep 19 13:26:40 2017
@@ -1829,6 +1829,45 @@ OverloadedOperatorKind BinaryOperator::g
   return OverOps[Opc];
 }
 
+bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
+  Opcode Opc,
+  Expr *LHS, Expr *RHS) {
+  if (Opc != BO_Add)
+return false;
+
+  // Check that we have one pointer and one integer operand.
+  Expr *PExp;
+  Expr *IExp;
+  if (LHS->getType()->isPointerType()) {
+if (!RHS->getType()->isIntegerType())
+  return false;
+PExp = LHS;
+IExp = RHS;
+  } else if (RHS->getType()->isPointerType()) {
+if (!LHS->getType()->isIntegerType())
+  return false;
+PExp = RHS;
+IExp = LHS;
+  } else {
+return false;
+  }
+
+  // Check that the pointer is a nullptr.
+  if (!PExp->IgnoreParenCasts()
+  ->i

r313684 - Fix 32-bit buildbots by removing tests that are dependent on pointer-size comparisons.

2017-09-19 Thread Andrew Kaylor via cfe-commits
Author: akaylor
Date: Tue Sep 19 14:43:01 2017
New Revision: 313684

URL: http://llvm.org/viewvc/llvm-project?rev=313684&view=rev
Log:
Fix 32-bit buildbots by removing tests that are dependent on pointer-size 
comparisons.

The recently behavior in the code that these tests were meant to be checking 
will be ammended as soon as a suitable change can be properly reviewed.


Modified:
cfe/trunk/test/CodeGen/nullptr-arithmetic.c
cfe/trunk/test/Sema/pointer-addition.c
cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp

Modified: cfe/trunk/test/CodeGen/nullptr-arithmetic.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/nullptr-arithmetic.c?rev=313684&r1=313683&r2=313684&view=diff
==
--- cfe/trunk/test/CodeGen/nullptr-arithmetic.c (original)
+++ cfe/trunk/test/CodeGen/nullptr-arithmetic.c Tue Sep 19 14:43:01 2017
@@ -17,26 +17,18 @@ int8_t *test1(intptr_t n) {
 // CHECK: inttoptr
 // CHECK-NOT: getelementptr
 
-// This doesn't meet the idiom because the offset type isn't pointer-sized.
-int8_t *test2(int8_t n) {
-  return NULLPTRI8 + n;
-}
-// CHECK-LABEL: test2
-// CHECK: getelementptr
-// CHECK-NOT: inttoptr
-
 // This doesn't meet the idiom because the element type is larger than a byte.
-int16_t *test3(intptr_t n) {
+int16_t *test2(intptr_t n) {
   return (int16_t*)0 + n;
 }
-// CHECK-LABEL: test3
+// CHECK-LABEL: test2
 // CHECK: getelementptr
 // CHECK-NOT: inttoptr
 
 // This doesn't meet the idiom because the offset is subtracted.
-int8_t* test4(intptr_t n) {
+int8_t* test3(intptr_t n) {
   return NULLPTRI8 - n;
 }
-// CHECK-LABEL: test4
+// CHECK-LABEL: test3
 // CHECK: getelementptr
 // CHECK-NOT: inttoptr

Modified: cfe/trunk/test/Sema/pointer-addition.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pointer-addition.c?rev=313684&r1=313683&r2=313684&view=diff
==
--- cfe/trunk/test/Sema/pointer-addition.c (original)
+++ cfe/trunk/test/Sema/pointer-addition.c Tue Sep 19 14:43:01 2017
@@ -27,6 +27,4 @@ void a(S* b, void* c) {
   // Cases that don't match the GNU inttoptr idiom get a different warning.
   f = (char*)0 - i; // expected-warning {{performing pointer arithmetic on a 
null pointer has undefined behavior}}
   int *g = (int*)0 + i; // expected-warning {{performing pointer arithmetic on 
a null pointer has undefined behavior}}
-  unsigned char j = (unsigned char)b;
-  f = (char*)0 + j; // expected-warning {{performing pointer arithmetic on a 
null pointer has undefined behavior}}
 }

Modified: cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp?rev=313684&r1=313683&r2=313684&view=diff
==
--- cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp Tue Sep 19 14:43:01 2017
@@ -2,7 +2,7 @@
 
 #include 
 
-void f(intptr_t offset, int8_t b) {
+void f(intptr_t offset) {
   // A zero offset from a nullptr is OK.
   char *f = (char*)nullptr + 0;
   int *g = (int*)0 + 0;
@@ -13,7 +13,6 @@ void f(intptr_t offset, int8_t b) {
   // Cases that don't match the GNU inttoptr idiom get a different warning.
   f = (char*)0 - offset; // expected-warning {{performing pointer arithmetic 
on a null pointer has undefined behavior if the offset is nonzero}}
   g = (int*)0 + offset; // expected-warning {{performing pointer arithmetic on 
a null pointer has undefined behavior if the offset is nonzero}}
-  f = (char*)0 + b; // expected-warning {{performing pointer arithmetic on a 
null pointer has undefined behavior if the offset is nonzero}}
 }
 
 // Value-dependent pointer arithmetic should not produce a nullptr warning.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r313784 - Remove offset size check in nullptr arithmetic handling

2017-09-20 Thread Andrew Kaylor via cfe-commits
Author: akaylor
Date: Wed Sep 20 11:06:44 2017
New Revision: 313784

URL: http://llvm.org/viewvc/llvm-project?rev=313784&view=rev
Log:
Remove offset size check in nullptr arithmetic handling

Differential Revision: https://reviews.llvm.org/D37042


Modified:
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/test/CodeGen/nullptr-arithmetic.c
cfe/trunk/test/Sema/pointer-addition.c
cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=313784&r1=313783&r2=313784&view=diff
==
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed Sep 20 11:06:44 2017
@@ -1837,17 +1837,14 @@ bool BinaryOperator::isNullPointerArithm
 
   // Check that we have one pointer and one integer operand.
   Expr *PExp;
-  Expr *IExp;
   if (LHS->getType()->isPointerType()) {
 if (!RHS->getType()->isIntegerType())
   return false;
 PExp = LHS;
-IExp = RHS;
   } else if (RHS->getType()->isPointerType()) {
 if (!LHS->getType()->isIntegerType())
   return false;
 PExp = RHS;
-IExp = LHS;
   } else {
 return false;
   }
@@ -1862,10 +1859,6 @@ bool BinaryOperator::isNullPointerArithm
   if (!PTy || !PTy->getPointeeType()->isCharType())
 return false;
 
-  // Check that the integer type is pointer-sized.
-  if (Ctx.getTypeSize(IExp->getType()) != Ctx.getTypeSize(PExp->getType()))
-return false;
-
   return true;
 }
 InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,

Modified: cfe/trunk/test/CodeGen/nullptr-arithmetic.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/nullptr-arithmetic.c?rev=313784&r1=313783&r2=313784&view=diff
==
--- cfe/trunk/test/CodeGen/nullptr-arithmetic.c (original)
+++ cfe/trunk/test/CodeGen/nullptr-arithmetic.c Wed Sep 20 11:06:44 2017
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -S %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -S %s -emit-llvm -triple i686-unknown-unknown -o - | 
FileCheck %s
+// RUN: %clang_cc1 -S %s -emit-llvm -triple x86_64-unknown-unknown -o - | 
FileCheck %s
 
 #include 
 
@@ -32,3 +34,14 @@ int8_t* test3(intptr_t n) {
 // CHECK-LABEL: test3
 // CHECK: getelementptr
 // CHECK-NOT: inttoptr
+
+// This checks the case where the offset isn't pointer-sized.
+// The front end will implicitly cast the offset to an integer, so we need to
+// make sure that doesn't cause problems on targets where integers and pointers
+// are not the same size.
+int8_t *test4(int8_t b) {
+  return NULLPTRI8 + b;
+}
+// CHECK-LABEL: test4
+// CHECK: inttoptr
+// CHECK-NOT: getelementptr

Modified: cfe/trunk/test/Sema/pointer-addition.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pointer-addition.c?rev=313784&r1=313783&r2=313784&view=diff
==
--- cfe/trunk/test/Sema/pointer-addition.c (original)
+++ cfe/trunk/test/Sema/pointer-addition.c Wed Sep 20 11:06:44 2017
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify 
-pedantic -Wextra -std=c11
+// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify 
-pedantic -Wextra -std=c11
 
 #include 
 

Modified: cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp?rev=313784&r1=313783&r2=313784&view=diff
==
--- cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr-arithmetic.cpp Wed Sep 20 11:06:44 2017
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -triple i686-unknown-unknown -verify 
-pedantic -Wextra -std=c++11
+// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify 
-pedantic -Wextra -std=c++11
 
 #include 
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits