Hi Chandler, I'm not certain why a separate check for this specific case is needed. Shouldn't this just fall out from the dataflow analysis for -Wunintialized? It seems inefficient to do both a special check for this specific case and do the dataflow analysis which should handle far more cases. If the dataflow analysis wasn't finding this case, that seems like a bug in the dataflow analysis. I don't think we should be doing recursive walk of every initialization expression when the dataflow analysis does the same thing.
On Mar 27, 2011, at 2:46 AM, Chandler Carruth <[email protected]> wrote: > Author: chandlerc > Date: Sun Mar 27 04:46:56 2011 > New Revision: 128376 > > URL: http://llvm.org/viewvc/llvm-project?rev=128376&view=rev > Log: > Diagnose uninitialized uses of a variable within its own initializer. > This is basically the same idea as the warning on uninitialized uses of > fields within an initializer list. As such, it is on by default and > under -Wuninitialized. > > Original patch by Richard Trieu, with some massaging from me on the > wording and grouping of the diagnostics. > > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/test/PCH/pragma-diag-section.cpp > cfe/trunk/test/PCH/pragma-diag.c > cfe/trunk/test/PCH/rdar8852495.c > cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Mar 27 04:46:56 > 2011 > @@ -871,6 +871,9 @@ > "uninitialized reference member is here">; > def warn_field_is_uninit : Warning<"field is uninitialized when used here">, > InGroup<Uninitialized>; > +def warn_uninit_self_reference_in_init : Warning< > + "variable %0 is uninitialized when used within its own initialization">, > + InGroup<Uninitialized>; > def warn_uninit_var : Warning<"variable %0 is possibly uninitialized when > used here">, > InGroup<Uninitialized>, DefaultIgnore; > def warn_maybe_uninit_var : > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Mar 27 04:46:56 2011 > @@ -25,6 +25,7 @@ > #include "clang/AST/DeclCXX.h" > #include "clang/AST/DeclObjC.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/EvaluatedExprVisitor.h" > #include "clang/AST/ExprCXX.h" > #include "clang/AST/StmtCXX.h" > #include "clang/AST/CharUnits.h" > @@ -4664,6 +4665,46 @@ > return true; > } > > +namespace { > + // Visits an initialization expression to see if OrigDecl is evaluated in > + // its own initialization and throws a warning if it does. > + class SelfReferenceChecker > + : public EvaluatedExprVisitor<SelfReferenceChecker> { > + Sema &S; > + Decl *OrigDecl; > + > + public: > + typedef EvaluatedExprVisitor<SelfReferenceChecker> Inherited; > + > + SelfReferenceChecker(Sema &S, Decl *OrigDecl) : Inherited(S.Context), > + S(S), OrigDecl(OrigDecl) > { } > + > + void VisitExpr(Expr *E) { > + if (isa<ObjCMessageExpr>(*E)) return; > + Inherited::VisitExpr(E); > + } > + > + void VisitImplicitCastExpr(ImplicitCastExpr *E) { > + CheckForSelfReference(E); > + Inherited::VisitImplicitCastExpr(E); > + } > + > + void CheckForSelfReference(ImplicitCastExpr *E) { > + if (E->getCastKind() != CK_LValueToRValue) return; > + Expr* SubExpr = E->getSubExpr()->IgnoreParenImpCasts(); > + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr); > + if (!DRE) return; > + Decl* ReferenceDecl = DRE->getDecl(); > + if (OrigDecl != ReferenceDecl) return; > + LookupResult Result(S, DRE->getNameInfo(), Sema::LookupOrdinaryName, > + Sema::NotForRedeclaration); > + S.Diag(SubExpr->getLocStart(), > diag::warn_uninit_self_reference_in_init) > + << Result.getLookupName() << OrigDecl->getLocation() > + << SubExpr->getSourceRange(); > + } > + }; > +} > + > /// AddInitializerToDecl - Adds the initializer Init to the > /// declaration dcl. If DirectInit is true, this is C++ direct > /// initialization rather than copy initialization. > @@ -4674,6 +4715,8 @@ > if (RealDecl == 0 || RealDecl->isInvalidDecl()) > return; > > + SelfReferenceChecker(*this, RealDecl).VisitExpr(Init); > + > if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) { > // With declarators parsed the way they are, the parser cannot > // distinguish between a normal initializer and a pure-specifier. > @@ -5231,7 +5274,7 @@ > if (Decl *D = Group[i]) > Decls.push_back(D); > > - return BuildDeclaratorGroup(Decls.data(), Decls.size(), > + return BuildDeclaratorGroup(Decls.data(), Decls.size(), > DS.getTypeSpecType() == DeclSpec::TST_auto); > } > > > Modified: cfe/trunk/test/PCH/pragma-diag-section.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-diag-section.cpp?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/test/PCH/pragma-diag-section.cpp (original) > +++ cfe/trunk/test/PCH/pragma-diag-section.cpp Sun Mar 27 04:46:56 2011 > @@ -12,7 +12,10 @@ > #pragma clang diagnostic ignored "-Wtautological-compare" > template <typename T> > struct TS { > - void m() { T b = b==b; } > + void m() { > + T a = 0; > + T b = a==a; > + } > }; > #pragma clang diagnostic pop > > > Modified: cfe/trunk/test/PCH/pragma-diag.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-diag.c?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/test/PCH/pragma-diag.c (original) > +++ cfe/trunk/test/PCH/pragma-diag.c Sun Mar 27 04:46:56 2011 > @@ -13,7 +13,8 @@ > #else > > void f() { > - int b = b==b; > + int a = 0; > + int b = a==a; > } > > #endif > > Modified: cfe/trunk/test/PCH/rdar8852495.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/rdar8852495.c?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/test/PCH/rdar8852495.c (original) > +++ cfe/trunk/test/PCH/rdar8852495.c Sun Mar 27 04:46:56 2011 > @@ -16,7 +16,8 @@ > #else > > int f() { > - int b = b==b; > + int a; > + int b = a==a; > unsigned x; > signed y; > return x == y; > > Modified: cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp?rev=128376&r1=128375&r2=128376&view=diff > ============================================================================== > --- cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp (original) > +++ cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp Sun Mar 27 > 04:46:56 2011 > @@ -2,14 +2,14 @@ > > // rdar://8365684 > struct S { > - void m1() { int b = b==b; } // expected-warning {{always evaluates to > true}} > + void m1() { int b; while (b==b); } // expected-warning {{always > evaluates to true}} > > #pragma clang diagnostic push > #pragma clang diagnostic ignored "-Wtautological-compare" > - void m2() { int b = b==b; } > + void m2() { int b; while (b==b); } > #pragma clang diagnostic pop > > - void m3() { int b = b==b; } // expected-warning {{always evaluates to > true}} > + void m3() { int b; while (b==b); } // expected-warning {{always > evaluates to true}} > }; > > //------------------------------------------------------------------------------ > @@ -18,7 +18,7 @@ > #pragma clang diagnostic ignored "-Wtautological-compare" > template <typename T> > struct TS { > - void m() { T b = b==b; } > + void m() { T b; while (b==b); } > }; > #pragma clang diagnostic pop > > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
