[cfe-commits] r128376 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/PCH/pragma-diag-section.cpp test/PCH/pragma-diag.c test/PCH/rdar8852495.c test/Preprocessor/pragma_diagnostic_sections.cpp
Ted Kremenek
kremenek at apple.com
Sun Mar 27 15:37:06 PDT 2011
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 <chandlerc at gmail.com> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list