r260776 - Make -Wnull-conversion more useful.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 12 16:58:53 PST 2016
Author: rtrieu
Date: Fri Feb 12 18:58:53 2016
New Revision: 260776
URL: http://llvm.org/viewvc/llvm-project?rev=260776&view=rev
Log:
Make -Wnull-conversion more useful.
When a null constant is used in a macro, walk through the macro stack to
determine where the null constant is written and where the context is located.
Only warn if both locations are within the same macro expansion. This helps
function-like macros which involve pointers be treated as if they were
functions.
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/SemaCXX/conversion.cpp
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=260776&r1=260775&r2=260776&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb 12 18:58:53 2016
@@ -7265,14 +7265,21 @@ void DiagnoseNullConversion(Sema &S, Exp
SourceLocation Loc = E->getSourceRange().getBegin();
+ // Venture through the macro stacks to get to the source of macro arguments.
+ // The new location is a better location than the complete location that was
+ // passed in.
+ while (S.SourceMgr.isMacroArgExpansion(Loc))
+ Loc = S.SourceMgr.getImmediateMacroCallerLoc(Loc);
+
+ while (S.SourceMgr.isMacroArgExpansion(CC))
+ CC = S.SourceMgr.getImmediateMacroCallerLoc(CC);
+
// __null is usually wrapped in a macro. Go up a macro if that is the case.
- if (NullKind == Expr::NPCK_GNUNull) {
- if (Loc.isMacroID()) {
- StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
- Loc, S.SourceMgr, S.getLangOpts());
- if (MacroName == "NULL")
- Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
- }
+ if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) {
+ StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
+ Loc, S.SourceMgr, S.getLangOpts());
+ if (MacroName == "NULL")
+ Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
}
// Only warn if the null and context location are in the same macro expansion.
Modified: cfe/trunk/test/SemaCXX/conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion.cpp?rev=260776&r1=260775&r2=260776&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion.cpp Fri Feb 12 18:58:53 2016
@@ -256,3 +256,45 @@ bool run() {
}
}
+
+// More tests with macros. Specficially, test function-like macros that either
+// have a pointer return type or take pointer arguments. Basically, if the
+// macro was changed into a function and Clang doesn't warn, then it shouldn't
+// warn for the macro either.
+namespace test13 {
+#define check_str_nullptr_13(str) ((str) ? str : nullptr)
+#define check_str_null_13(str) ((str) ? str : NULL)
+#define test13(condition) if (condition) return;
+#define identity13(arg) arg
+#define CHECK13(condition) test13(identity13(!(condition)))
+
+void function1(const char* str) {
+ CHECK13(check_str_nullptr_13(str));
+ CHECK13(check_str_null_13(str));
+}
+
+bool some_bool_function(bool);
+void function2() {
+ CHECK13(some_bool_function(nullptr)); // expected-warning{{implicit conversion of nullptr constant to 'bool'}}
+ CHECK13(some_bool_function(NULL)); // expected-warning{{implicit conversion of NULL constant to 'bool'}}
+}
+
+#define run_check_nullptr_13(str) \
+ if (check_str_nullptr_13(str)) return;
+#define run_check_null_13(str) \
+ if (check_str_null_13(str)) return;
+void function3(const char* str) {
+ run_check_nullptr_13(str)
+ run_check_null_13(str)
+ if (check_str_nullptr_13(str)) return;
+ if (check_str_null_13(str)) return;
+}
+
+void run(int* ptr);
+#define conditional_run_13(ptr) \
+ if (ptr) run(ptr);
+void function4() {
+ conditional_run_13(nullptr);
+ conditional_run_13(NULL);
+}
+}
More information about the cfe-commits
mailing list