r202216 - PR16074, implement warnings to catch pointer to boolean true and pointer to
Richard Trieu
rtrieu at google.com
Tue Feb 25 18:36:06 PST 2014
Author: rtrieu
Date: Tue Feb 25 20:36:06 2014
New Revision: 202216
URL: http://llvm.org/viewvc/llvm-project?rev=202216&view=rev
Log:
PR16074, implement warnings to catch pointer to boolean true and pointer to
null comparison when the pointer is known to be non-null.
This catches the array to pointer decay, function to pointer decay and
address of variables. This does not catch address of function since this
has been previously used to silence a warning.
Pointer to bool conversion is under -Wbool-conversion.
Pointer to null comparison is under -Wtautological-pointer-compare, a sub-group
of -Wtautological-compare.
void foo() {
int arr[5];
int x;
// warn on these conditionals
if (foo);
if (arr);
if (&x);
if (foo == null);
if (arr == null);
if (&x == null);
if (&foo); // no warning
}
Removed:
cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Analysis/casts.c
cfe/trunk/test/Analysis/ptr-arith.c
cfe/trunk/test/Analysis/stackaddrleak.c
cfe/trunk/test/Analysis/weak-functions.c
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
cfe/trunk/test/Sema/const-eval.c
cfe/trunk/test/Sema/static-init.c
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp
cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp
cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Feb 25 20:36:06 2014
@@ -285,8 +285,10 @@ def StringPlusInt : DiagGroup<"string-pl
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
def TautologicalCompare : DiagGroup<"tautological-compare",
- [TautologicalOutOfRangeCompare]>;
+ [TautologicalOutOfRangeCompare,
+ TautologicalPointerCompare]>;
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 25 20:36:06 2014
@@ -2322,12 +2322,19 @@ def warn_impcast_null_pointer_to_integer
def warn_impcast_floating_point_to_bool : Warning<
"implicit conversion turns floating-point number into bool: %0 to %1">,
InGroup<ImplicitConversionFloatingPointToBool>;
-def warn_impcast_function_to_bool : Warning<
- "address of function %q0 will always evaluate to 'true'">,
+
+def warn_impcast_pointer_to_bool : Warning<
+ "address of%select{| function| array}0 '%1' will always evaluate to "
+ "'true'">,
InGroup<BoolConversion>;
-def note_function_to_bool_silence : Note<
+def warn_null_pointer_compare : Warning<
+ "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
+ "equal to a null pointer is always %select{true|false}2">,
+ InGroup<TautologicalPointerCompare>;
+
+def note_function_warning_silence : Note<
"prefix with the address-of operator to silence this warning">;
-def note_function_to_bool_call : Note<
+def note_function_to_function_call : Note<
"suffix with parentheses to turn this into a function call">;
def warn_impcast_objective_c_literal_to_bool : Warning<
"implicit boolean conversion of Objective-C object literal always "
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Feb 25 20:36:06 2014
@@ -7470,6 +7470,10 @@ public:
bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
SourceLocation QuestionLoc);
+ void DiagnoseAlwaysNonNullPointer(Expr *E,
+ Expr::NullPointerConstantKind NullType,
+ bool IsEqual, SourceRange Range);
+
/// type checking for vector binary operators.
QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign);
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Feb 25 20:36:06 2014
@@ -5690,35 +5690,10 @@ void CheckImplicitConversion(Sema &S, Ex
return DiagnoseImpCast(S, E, T, CC,
diag::warn_impcast_objective_c_literal_to_bool);
}
- if (Source->isFunctionType()) {
- // Warn on function to bool. Checks free functions and static member
- // functions. Weakly imported functions are excluded from the check,
- // since it's common to test their value to check whether the linker
- // found a definition for them.
- ValueDecl *D = 0;
- if (DeclRefExpr* R = dyn_cast<DeclRefExpr>(E)) {
- D = R->getDecl();
- } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
- D = M->getMemberDecl();
- }
-
- if (D && !D->isWeak()) {
- if (FunctionDecl* F = dyn_cast<FunctionDecl>(D)) {
- S.Diag(E->getExprLoc(), diag::warn_impcast_function_to_bool)
- << F << E->getSourceRange() << SourceRange(CC);
- S.Diag(E->getExprLoc(), diag::note_function_to_bool_silence)
- << FixItHint::CreateInsertion(E->getExprLoc(), "&");
- QualType ReturnType;
- UnresolvedSet<4> NonTemplateOverloads;
- S.tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
- if (!ReturnType.isNull()
- && ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
- S.Diag(E->getExprLoc(), diag::note_function_to_bool_call)
- << FixItHint::CreateInsertion(
- S.getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
- return;
- }
- }
+ if (Source->isPointerType() || Source->canDecayToPointerType()) {
+ // Warn on pointer to bool conversion that is always true.
+ S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
+ SourceRange(CC));
}
}
@@ -6055,6 +6030,125 @@ void AnalyzeImplicitConversions(Sema &S,
} // end anonymous namespace
+enum {
+ AddressOf,
+ FunctionPointer,
+ ArrayPointer
+};
+
+/// \brief Diagnose pointers that are always non-null.
+/// \param E the expression containing the pointer
+/// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
+/// compared to a null pointer
+/// \param IsEqual True when the comparison is equal to a null pointer
+/// \param Range Extra SourceRange to highlight in the diagnostic
+void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
+ Expr::NullPointerConstantKind NullKind,
+ bool IsEqual, SourceRange Range) {
+
+ // Don't warn inside macros.
+ if (E->getExprLoc().isMacroID())
+ return;
+ E = E->IgnoreImpCasts();
+
+ const bool IsCompare = NullKind != Expr::NPCK_NotNull;
+
+ bool IsAddressOf = false;
+
+ if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+ if (UO->getOpcode() != UO_AddrOf)
+ return;
+ IsAddressOf = true;
+ E = UO->getSubExpr();
+ }
+
+ // Expect to find a single Decl. Skip anything more complicated.
+ ValueDecl *D = 0;
+ if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {
+ D = R->getDecl();
+ } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+ D = M->getMemberDecl();
+ }
+
+ // Weak Decls can be null.
+ if (!D || D->isWeak())
+ return;
+
+ QualType T = D->getType();
+ const bool IsArray = T->isArrayType();
+ const bool IsFunction = T->isFunctionType();
+
+ if (IsAddressOf) {
+ // Address of function is used to silence the function warning.
+ if (IsFunction)
+ return;
+ // Address of reference can be null.
+ if (T->isReferenceType())
+ return;
+ }
+
+ // Found nothing.
+ if (!IsAddressOf && !IsFunction && !IsArray)
+ return;
+
+ // Pretty print the expression for the diagnostic.
+ std::string Str;
+ llvm::raw_string_ostream S(Str);
+ E->printPretty(S, 0, getPrintingPolicy());
+
+ unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
+ : diag::warn_impcast_pointer_to_bool;
+ unsigned DiagType;
+ if (IsAddressOf)
+ DiagType = AddressOf;
+ else if (IsFunction)
+ DiagType = FunctionPointer;
+ else if (IsArray)
+ DiagType = ArrayPointer;
+ else
+ llvm_unreachable("Could not determine diagnostic.");
+ Diag(E->getExprLoc(), DiagID) << DiagType << S.str() << E->getSourceRange()
+ << Range << IsEqual;
+
+ if (!IsFunction)
+ return;
+
+ // Suggest '&' to silence the function warning.
+ Diag(E->getExprLoc(), diag::note_function_warning_silence)
+ << FixItHint::CreateInsertion(E->getLocStart(), "&");
+
+ // Check to see if '()' fixit should be emitted.
+ QualType ReturnType;
+ UnresolvedSet<4> NonTemplateOverloads;
+ tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
+ if (ReturnType.isNull())
+ return;
+
+ if (IsCompare) {
+ // There are two cases here. If there is null constant, the only suggest
+ // for a pointer return type. If the null is 0, then suggest if the return
+ // type is a pointer or an integer type.
+ if (!ReturnType->isPointerType()) {
+ if (NullKind == Expr::NPCK_ZeroExpression ||
+ NullKind == Expr::NPCK_ZeroLiteral) {
+ if (!ReturnType->isIntegerType())
+ return;
+ } else {
+ return;
+ }
+ }
+ } else { // !IsCompare
+ // For function to bool, only suggest if the function pointer has bool
+ // return type.
+ if (!ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
+ return;
+ }
+ Diag(E->getExprLoc(), diag::note_function_to_function_call)
+ << FixItHint::CreateInsertion(
+ getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
+}
+
+
/// Diagnoses "dangerous" implicit conversions within the given
/// expression (which is a full expression). Implements -Wconversion
/// and -Wsign-compare.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 25 20:36:06 2014
@@ -7867,10 +7867,22 @@ QualType Sema::CheckCompareOperands(Expr
return ResultTy;
}
- bool LHSIsNull = LHS.get()->isNullPointerConstant(Context,
- Expr::NPC_ValueDependentIsNull);
- bool RHSIsNull = RHS.get()->isNullPointerConstant(Context,
- Expr::NPC_ValueDependentIsNull);
+ const Expr::NullPointerConstantKind LHSNullKind =
+ LHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+ const Expr::NullPointerConstantKind RHSNullKind =
+ RHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+ bool LHSIsNull = LHSNullKind != Expr::NPCK_NotNull;
+ bool RHSIsNull = RHSNullKind != Expr::NPCK_NotNull;
+
+ if (!IsRelational && LHSIsNull != RHSIsNull) {
+ bool IsEquality = Opc == BO_EQ;
+ if (RHSIsNull)
+ DiagnoseAlwaysNonNullPointer(LHS.get(), RHSNullKind, IsEquality,
+ RHS.get()->getSourceRange());
+ else
+ DiagnoseAlwaysNonNullPointer(RHS.get(), LHSNullKind, IsEquality,
+ LHS.get()->getSourceRange());
+ }
// All of the following pointer-related warnings are GCC extensions, except
// when handling null pointer constants.
Modified: cfe/trunk/test/Analysis/casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/casts.c (original)
+++ cfe/trunk/test/Analysis/casts.c Tue Feb 25 20:36:06 2014
@@ -110,7 +110,8 @@ void castsToBool() {
clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}}
int localInt;
- clang_analyzer_eval(&localInt); // expected-warning{{TRUE}}
+ int* ptr = &localInt;
+ clang_analyzer_eval(ptr); // expected-warning{{TRUE}}
clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}}
clang_analyzer_eval("abc"); // expected-warning{{TRUE}}
Modified: cfe/trunk/test/Analysis/ptr-arith.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ptr-arith.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ptr-arith.c (original)
+++ cfe/trunk/test/Analysis/ptr-arith.c Tue Feb 25 20:36:06 2014
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
void clang_analyzer_eval(int);
Modified: cfe/trunk/test/Analysis/stackaddrleak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/stackaddrleak.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/stackaddrleak.c (original)
+++ cfe/trunk/test/Analysis/stackaddrleak.c Tue Feb 25 20:36:06 2014
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
typedef __INTPTR_TYPE__ intptr_t;
char const *p;
Modified: cfe/trunk/test/Analysis/weak-functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/weak-functions.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/weak-functions.c (original)
+++ cfe/trunk/test/Analysis/weak-functions.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
#define NULL 0
void clang_analyzer_eval(int);
void myFunc();
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp Tue Feb 25 20:36:06 2014
@@ -163,7 +163,8 @@ void shrink_int() {
Agg<bool> b3 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}}
// Conversions from pointers to booleans aren't narrowing conversions.
- Agg<bool> b = {&b1}; // OK
+ Agg<bool>* ptr = &b1;
+ Agg<bool> b = {ptr}; // OK
Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp Tue Feb 25 20:36:06 2014
@@ -164,7 +164,8 @@ void shrink_int() {
Agg<bool> b3 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
// Conversions from pointers to booleans aren't narrowing conversions.
- Agg<bool> b = {&b1}; // OK
+ Agg<bool>* ptr = &b1;
+ Agg<bool> b = {ptr}; // OK
Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp Tue Feb 25 20:36:06 2014
@@ -15,7 +15,7 @@ bool b4 = !E;
bool b5 = !F;
// -- pointer,
-bool b6 = !&b4;
+bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 'true'}}
void f();
bool b61 = !&f;
Modified: cfe/trunk/test/Sema/const-eval.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Sema/const-eval.c (original)
+++ cfe/trunk/test/Sema/const-eval.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s -Wno-tautological-pointer-compare
#define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
int x;
Modified: cfe/trunk/test/Sema/static-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-init.c?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/Sema/static-init.c (original)
+++ cfe/trunk/test/Sema/static-init.c Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion %s
typedef __typeof((int*) 0 - (int*) 0) intptr_t;
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
namespace StaticAssertFoldTest {
Modified: cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int -Wno-tautological-pointer-compare %s
#include <stddef.h>
void f() {
Modified: cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp Tue Feb 25 20:36:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
void foo() {
int a;
Modified: cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-bool-conversion.cpp Tue Feb 25 20:36:06 2014
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace BooleanFalse {
int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
@@ -22,3 +23,98 @@ double f(...);
// isn't flagged.
template <int N> struct S {};
S<sizeof(f(false))> s;
+
+}
+
+namespace Function {
+void f1();
+
+struct S {
+ static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+ static void f4() __attribute__((weak_import));
+};
+
+bool f5();
+bool f6(int);
+
+void bar() {
+ bool b;
+
+ b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}} \
+ expected-note {{suffix with parentheses to turn this into a function call}}
+ b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+
+ // implicit casts of weakly imported symbols are ok:
+ b = f3;
+ if (f3) {}
+ b = S2::f4;
+ if (S2::f4) {}
+}
+}
+
+namespace Array {
+ #define GetValue(ptr) ((ptr) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a) {}
+ if (a) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b) {}
+ // expected-warning at -1{{address of array 'b' will always evaluate to 'true'}}
+ if (b) {}
+ // expected-warning at -1{{address of array 'b' will always evaluate to 'true'}}
+ if (c.x) {}
+ // expected-warning at -1{{address of array 'c.x' will always evaluate to 'true'}}
+ if (str) {}
+ // expected-warning at -1{{address of array 'str' will always evaluate to 'true'}}
+ }
+}
+
+namespace Pointer {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a) {}
+ }
+ void test() {
+ S s;
+ if (&b) {}
+ // expected-warning at -1{{address of 'b' will always evaluate to 'true'}}
+ if (&c) {}
+ // expected-warning at -1{{address of 'c' will always evaluate to 'true'}}
+ if (&s.a) {}
+ // expected-warning at -1{{address of 's.a' will always evaluate to 'true'}}
+ if (&s.b) {}
+ // expected-warning at -1{{address of 's.b' will always evaluate to 'true'}}
+ if (&S::a) {}
+ // expected-warning at -1{{address of 'S::a' will always evaluate to 'true'}}
+ }
+}
Removed: cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp?rev=202215&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-func-as-bool.cpp (removed)
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
-
-void f1();
-
-struct S {
- static void f2();
-};
-
-extern void f3() __attribute__((weak_import));
-
-struct S2 {
- static void f4() __attribute__((weak_import));
-};
-
-bool f5();
-bool f6(int);
-
-void bar() {
- bool b;
-
- b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}} \
- expected-note {{suffix with parentheses to turn this into a function call}}
- b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
-
- // implicit casts of weakly imported symbols are ok:
- b = f3;
- if (f3) {}
- b = S2::f4;
- if (S2::f4) {}
-}
Modified: cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-tautological-compare.cpp Tue Feb 25 20:36:06 2014
@@ -25,3 +25,114 @@ namespace RuntimeBehavior {
if (x < kintmax) {}
}
}
+
+namespace ArrayCompare {
+ #define GetValue(ptr) ((ptr != 0) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a == 0) {}
+ if (a != 0) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b == 0) {}
+ // expected-warning at -1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (b != 0) {}
+ // expected-warning at -1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (0 == b) {}
+ // expected-warning at -1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (0 != b) {}
+ // expected-warning at -1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (c.x == 0) {}
+ // expected-warning at -1{{comparison of array 'c.x' equal to a null pointer is always false}}
+ if (c.x != 0) {}
+ // expected-warning at -1{{comparison of array 'c.x' not equal to a null pointer is always true}}
+ if (str == 0) {}
+ // expected-warning at -1{{comparison of array 'str' equal to a null pointer is always false}}
+ if (str != 0) {}
+ // expected-warning at -1{{comparison of array 'str' not equal to a null pointer is always true}}
+ }
+}
+
+namespace FunctionCompare {
+ #define CallFunction(f) ((f != 0) ? f() : 0)
+ extern void a() __attribute__((weak));
+ void fun1();
+ int fun2();
+ int* fun3();
+ int* fun4(int);
+ class S {
+ public:
+ static int foo();
+ };
+ void ignore() {
+ if (a == 0) {}
+ if (0 != a) {}
+ (void)CallFunction(fun2);
+ }
+ void test() {
+ if (fun1 == 0) {}
+ // expected-warning at -1{{comparison of function 'fun1' equal to a null pointer is always false}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ if (fun2 == 0) {}
+ // expected-warning at -1{{comparison of function 'fun2' equal to a null pointer is always false}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+ if (fun3 == 0) {}
+ // expected-warning at -1{{comparison of function 'fun3' equal to a null pointer is always false}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+ if (fun4 == 0) {}
+ // expected-warning at -1{{comparison of function 'fun4' equal to a null pointer is always false}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun1) {}
+ // expected-warning at -1{{comparison of function 'fun1' not equal to a null pointer is always true}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun2) {}
+ // expected-warning at -1{{comparison of function 'fun2' not equal to a null pointer is always true}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun3) {}
+ // expected-warning at -1{{comparison of function 'fun3' not equal to a null pointer is always true}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+ if (nullptr != fun4) {}
+ // expected-warning at -1{{comparison of function 'fun4' not equal to a null pointer is always true}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ if (S::foo == 0) {}
+ // expected-warning at -1{{comparison of function 'S::foo' equal to a null pointer is always false}}
+ // expected-note at -2{{prefix with the address-of operator to silence this warning}}
+ // expected-note at -3{{suffix with parentheses to turn this into a function call}}
+ }
+}
+
+namespace PointerCompare {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a == 0) {}
+ }
+ void test() {
+ S s;
+ if (&b == 0) {}
+ // expected-warning at -1{{comparison of address of 'b' equal to a null pointer is always false}}
+ if (&c == 0) {}
+ // expected-warning at -1{{comparison of address of 'c' equal to a null pointer is always false}}
+ if (&s.a == 0) {}
+ // expected-warning at -1{{comparison of address of 's.a' equal to a null pointer is always false}}
+ if (&s.b == 0) {}
+ // expected-warning at -1{{comparison of address of 's.b' equal to a null pointer is always false}}
+ if (&S::a == 0) {}
+ // expected-warning at -1{{comparison of address of 'S::a' equal to a null pointer is always false}}
+ }
+}
Modified: cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp?rev=202216&r1=202215&r2=202216&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp (original)
+++ cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp Tue Feb 25 20:36:06 2014
@@ -45,9 +45,15 @@ int main()
+oneT<int>; // expected-warning {{expression result unused}}
-oneT<int>; //expected-error {{invalid argument type}}
oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
- // expected-note {{use '=' to turn this equality comparison into an assignment}}
- 0 == oneT<int>; // expected-warning {{equality comparison result unused}}
- 0 != oneT<int>; // expected-warning {{inequality comparison result unused}}
+ // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+ // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+ // expected-note {{prefix with the address-of operator to silence this warning}}
+ 0 == oneT<int>; // expected-warning {{equality comparison result unused}} \
+ // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+ // expected-note {{prefix with the address-of operator to silence this warning}}
+ 0 != oneT<int>; // expected-warning {{inequality comparison result unused}} \
+ // expected-warning {{comparison of function 'oneT<int>' not equal to a null pointer is always true}} \
+ // expected-note {{prefix with the address-of operator to silence this warning}}
(false ? one : oneT<int>); // expected-warning {{expression result unused}}
void (*p1)(int); p1 = oneT<int>;
@@ -69,7 +75,9 @@ int main()
two < two; //expected-error 2 {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{invalid operands to binary expression ('void' and 'void')}}
twoT<int> < twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
- // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+ // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+ // expected-note {{prefix with the address-of operator to silence this warning}}
}
More information about the cfe-commits
mailing list