diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 1fc3c1aeff30..62f45f5c916b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4250,9 +4250,10 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation Loc = E->getSourceRange().getBegin(); if (Loc.isMacroID()) Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first; - S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) - << T << clang::SourceRange(CC) - << FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T)); + if (!Loc.isMacroID() || CC.isMacroID()) + S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) + << T << clang::SourceRange(CC) + << FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T)); return; } @@ -4345,14 +4346,15 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, return; } -void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T); +void CheckConditionalOperator(Sema &S, ConditionalOperator *E, + SourceLocation CC, QualType T); void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext) { E = E->IgnoreParenImpCasts(); if (isa(E)) - return CheckConditionalOperator(S, cast(E), T); + return CheckConditionalOperator(S, cast(E), CC, T); AnalyzeImplicitConversions(S, E, CC); if (E->getType() != T) @@ -4360,9 +4362,8 @@ void CheckConditionalOperand(Sema &S, Expr *E, QualType T, return; } -void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) { - SourceLocation CC = E->getQuestionLoc(); - +void CheckConditionalOperator(Sema &S, ConditionalOperator *E, + SourceLocation CC, QualType T) { AnalyzeImplicitConversions(S, E->getCond(), CC); bool Suspicious = false; @@ -4404,7 +4405,7 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { // were being fed directly into the output. if (isa(E)) { ConditionalOperator *CO = cast(E); - CheckConditionalOperator(S, CO, T); + CheckConditionalOperator(S, CO, CC, T); return; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 647b9c1fc942..e81787d5a4bb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3314,7 +3314,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, return ExprError(); Expr *Arg = Result.takeAs(); - CheckImplicitConversions(Arg, Arg->getExprLoc()); + CheckImplicitConversions(Arg, Param->getOuterLocStart()); // Build the default argument expression. return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg)); } diff --git a/clang/test/SemaCXX/conversion.cpp b/clang/test/SemaCXX/conversion.cpp index 4b44bede8dbc..60e440f234a8 100644 --- a/clang/test/SemaCXX/conversion.cpp +++ b/clang/test/SemaCXX/conversion.cpp @@ -73,13 +73,14 @@ void test3() { // Use FileCheck to ensure we don't get any unnecessary macro-expansion notes // (that don't appear as 'real' notes & can't be seen/tested by -verify) // CHECK-NOT: note: - // CHECK: note: expanded from macro 'FNULL' -#define FNULL NULL - int a2 = FNULL; // expected-warning {{implicit conversion of NULL constant to 'int'}} - // CHECK-NOT: note: // CHECK: note: expanded from macro 'FINIT' #define FINIT int a3 = NULL; FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}} + + // we don't catch the case of #define FOO NULL ... int i = FOO; but that seems a bit narrow anyway + // and avoiding that helps us skip these cases: +#define NULL_COND(cond) ((cond) ? &a : NULL) + bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary } namespace test4 {