r313666 - Teach clang to tolerate the 'p = nullptr + n' idiom used by glibc
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.
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
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