[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