From 609e3170841dac81c3b7b6b9eccb9c520e42c9b2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 2 Feb 2011 23:35:53 +0000 Subject: [PATCH] Based on user feedback, swap -Wuninitialized diagnostics to have the warning refer to the bad use, and the note to the variable declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124758 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 11 +-- lib/Sema/AnalysisBasedWarnings.cpp | 69 ++++++++++--------- test/Sema/uninit-variables.c | 78 +++++++++++----------- test/SemaCXX/uninit-variables.cpp | 4 +- test/SemaObjC/uninit-variables.m | 4 +- 5 files changed, 86 insertions(+), 80 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1a9d694805..7bf12f26ec 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -836,12 +836,13 @@ def note_uninit_reference_member : Note< "uninitialized reference member is here">; def warn_field_is_uninit : Warning<"field is uninitialized when used here">, InGroup; -def warn_uninit_var : Warning<"use of uninitialized variable %0">, +def warn_uninit_var : Warning<"variable %0 is possibly uninitialized when used here">, + InGroup, DefaultIgnore; +def note_uninit_var_def : Note< + "variable %0 is declared here">; +def warn_uninit_var_captured_by_block : Note< + "variable %0 is possibly uninitialized when captured by block">, InGroup, DefaultIgnore; -def note_uninit_var : Note< - "variable %0 is possibly uninitialized when used here">; -def note_uninit_var_captured_by_block : Note< - "variable %0 is possibly uninitialized when captured by block">; def note_var_fixit_add_initialization : Note< "add initialization to silence this warning">; def err_init_incomplete_type : Error<"initialization of incomplete type %0">; diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 3e6cd81b76..0e7846f021 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -393,14 +393,13 @@ public: void flushDiagnostics() { if (!uses) return; - + for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) { const VarDecl *vd = i->first; UsesVec *vec = i->second; - - S.Diag(vd->getLocStart(), diag::warn_uninit_var) - << vd->getDeclName() << vd->getSourceRange(); - + + bool fixitIssued = false; + // Sort the uses by their SourceLocations. While not strictly // guaranteed to produce them in line/column order, this will provide // a stable ordering. @@ -409,43 +408,49 @@ public: for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) { if (const DeclRefExpr *dr = dyn_cast(*vi)) { - S.Diag(dr->getLocStart(), diag::note_uninit_var) - << vd->getDeclName() << dr->getSourceRange(); + S.Diag(dr->getLocStart(), diag::warn_uninit_var) + << vd->getDeclName() << dr->getSourceRange(); } else { const BlockExpr *be = cast(*vi); - S.Diag(be->getLocStart(), diag::note_uninit_var_captured_by_block) + S.Diag(be->getLocStart(), diag::warn_uninit_var_captured_by_block) << vd->getDeclName(); } - } + + // Report where the variable was declared. + S.Diag(vd->getLocStart(), diag::note_uninit_var_def) + << vd->getDeclName(); + + // Only report the fixit once. + if (fixitIssued) + continue; + + fixitIssued = true; - // Suggest possible initialization (if any). - const char *initialization = 0; - QualType vdTy = vd->getType().getCanonicalType(); + // Suggest possible initialization (if any). + const char *initialization = 0; + QualType vdTy = vd->getType().getCanonicalType(); - if (vdTy->getAs()) { - // Check if 'nil' is defined. - if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) - initialization = " = nil"; - else + if (vdTy->getAs()) { + // Check if 'nil' is defined. + if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) + initialization = " = nil"; + else + initialization = " = 0"; + } + else if (vdTy->isRealFloatingType()) + initialization = " = 0.0"; + else if (vdTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus) + initialization = " = false"; + else if (vdTy->isScalarType()) initialization = " = 0"; - } - else if (vdTy->isRealFloatingType()) { - initialization = " = 0.0"; - } - else if (vdTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus) { - initialization = " = false"; - } - else if (vdTy->isScalarType()) { - initialization = " = 0"; - } - if (initialization) { - SourceLocation loc = S.PP.getLocForEndOfToken(vd->getLocEnd()); - S.Diag(loc, diag::note_var_fixit_add_initialization) - << FixItHint::CreateInsertion(loc, initialization); + if (initialization) { + SourceLocation loc = S.PP.getLocForEndOfToken(vd->getLocEnd()); + S.Diag(loc, diag::note_var_fixit_add_initialization) + << FixItHint::CreateInsertion(loc, initialization); + } } - delete vec; } delete uses; diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index f869ef2870..ce3f93d590 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fblocks %s -verify int test1() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } int test2() { @@ -17,28 +17,28 @@ int test3() { } int test4() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - ++x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + ++x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} return x; } int test5() { - int x, y; // expected-warning{{use of uninitialized variable 'y'}} expected-note{{add initialization to silence this warning}} - x = y; // expected-note{{variable 'y' is possibly uninitialized when used here}} + int x, y; // expected-note{{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}} + x = y; // expected-warning{{variable 'y' is possibly uninitialized when used here}} return x; } int test6() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - x += 2; // expected-note{{variable 'x' is possibly uninitialized when used here}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + x += 2; // expected-warning{{variable 'x' is possibly uninitialized when used here}} return x; } int test7(int y) { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} if (y) x = 1; - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } int test8(int y) { @@ -47,37 +47,37 @@ int test8(int y) { x = 1; else x = 0; - return x; // no-warning + return x; } int test9(int n) { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} for (unsigned i = 0 ; i < n; ++i) { if (i == n - 1) break; x = 1; } - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } int test10(unsigned n) { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} for (unsigned i = 0 ; i < n; ++i) { x = 1; } - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } int test11(unsigned n) { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} for (unsigned i = 0 ; i <= n; ++i) { x = 1; } - return x; //expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } void test12(unsigned n) { - for (unsigned i ; n ; ++i) ; // expected-warning{{use of uninitialized variable 'i'}} expected-note{{variable 'i' is possibly uninitialized when used here}}} expected-note{{add initialization to silence this warning}} + for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is possibly uninitialized when used here}} expected-note{{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}} } int test13() { @@ -92,7 +92,7 @@ void test14() { } void test15() { - int x = x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{variable 'x' is possibly uninitialized when used here}} expected-note{{add initialization to silence this warning}} + int x = x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} } // Don't warn in the following example; shows dataflow confluence. @@ -106,8 +106,8 @@ void test16() { void test17() { // Don't warn multiple times about the same uninitialized variable // along the same path. - int *x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - *x = 1; // expected-note{{variable 'x' is possibly uninitialized when used here}} + int *x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + *x = 1; // expected-warning{{variable 'x' is possibly uninitialized when used here}} *x = 1; // no-warning } @@ -130,16 +130,16 @@ int test19() { } int test20() { - int z; // expected-warning{{use of uninitialized variable 'z'}} expected-note{{add initialization to silence this warning}} + int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}} if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) - return z; // expected-note{{variable 'z' is possibly uninitialized when used here}} + return z; // expected-warning{{variable 'z' is possibly uninitialized when used here}} return 0; } int test21(int x, int y) { - int z; // expected-warning{{use of uninitialized variable 'z'}} expected-note{{add initialization to silence this warning}} + int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}} if ((x && y) || test19_aux3(&z) || test19_aux2()) - return z; // expected-note{{variable 'z' is possibly uninitialized when used here}} + return z; // expected-warning{{variable 'z' is possibly uninitialized when used here}} return 0; } @@ -162,23 +162,23 @@ int test23() { // conditionals. This possibly can be handled by making the CFG itself // represent such control-dependencies, but it is a niche case. int test24(int flag) { - unsigned val; // expected-warning{{use of uninitialized variable 'val'}} expected-note{{add initialization to silence this warning}} + unsigned val; // expected-note{{variable 'val' is declared here}} expected-note{{add initialization to silence this warning}} if (flag) val = 1; if (!flag) val = 1; - return val; // expected-note{{variable 'val' is possibly uninitialized when used here}} + return val; // expected-warning{{variable 'val' is possibly uninitialized when used here}} } float test25() { - float x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + float x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } typedef int MyInt; MyInt test26() { - MyInt x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + MyInt x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } // Test handling of sizeof(). @@ -188,13 +188,13 @@ int test27() { } int test28() { - int len; // expected-warning{{use of uninitialized variable 'len'}} expected-note{{add initialization to silence this warning}} - return sizeof(int[len]); // expected-note{{variable 'len' is possibly uninitialized when used here}} + int len; // expected-note{{variable 'len' is declared here}} expected-note{{add initialization to silence this warning}} + return sizeof(int[len]); // expected-warning{{variable 'len' is possibly uninitialized when used here}} } void test29() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - (void) ^{ (void) x; }; // expected-note{{variable 'x' is possibly uninitialized when captured by block}} + int x; + (void) ^{ (void) x; }; } void test30() { @@ -218,9 +218,9 @@ void test_33() { } int test_34() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}} (void) x; - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } // Test that this case doesn't crash. @@ -232,10 +232,10 @@ void test35(int x) { // Test handling of indirect goto. void test36() { - void **pc; // expected-warning{{use of uninitialized variable 'pc'}} expected-note{{ add initialization to silence this warning}} + void **pc; // expected-note{{variable 'pc' is declared here}} expected-note{{add initialization to silence this warning}} void *dummy[] = { &&L1, &&L2 }; L1: - goto *pc; // expected-note{{variable 'pc' is possibly uninitialized when used here}} + goto *pc; // expected-warning{{variable 'pc' is possibly uninitialized when used here}} L2: goto *pc; } diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp index 572e0aac81..cc5018a5e8 100644 --- a/test/SemaCXX/uninit-variables.cpp +++ b/test/SemaCXX/uninit-variables.cpp @@ -33,11 +33,11 @@ unsigned test3_b() { return x; // no-warning } unsigned test3_c() { - unsigned x ; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} + unsigned x; // expected-note{{declared here}} expected-note{{add initialization}} const bool flag = false; if (flag && (x = test3_aux()) == 0) { x = 1; } - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } diff --git a/test/SemaObjC/uninit-variables.m b/test/SemaObjC/uninit-variables.m index f3917f3922..22d44384b4 100644 --- a/test/SemaObjC/uninit-variables.m +++ b/test/SemaObjC/uninit-variables.m @@ -3,8 +3,8 @@ // Duplicated from uninit-variables.c. // Test just to ensure the analysis is working. int test1() { - int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}} - return x; // expected-note{{variable 'x' is possibly uninitialized when used here}} + int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization}} + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} } // Test ObjC fast enumeration. -- 2.40.0