[cfe-commits] r132191 - in /cfe/trunk: lib/Sema/JumpDiagnostics.cpp test/CXX/stmt.stmt/stmt.dcl/p3.cpp

Eli Friedman eli.friedman at gmail.com
Fri May 27 09:54:12 PDT 2011


On Fri, May 27, 2011 at 9:05 AM, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Fri May 27 11:05:29 2011
> New Revision: 132191
>
> URL: http://llvm.org/viewvc/llvm-project?rev=132191&view=rev
> Log:
> Update the jump-scope checker for local variables with initializers,
> so that it looks at the initializer of a local variable of class type
> (or array thereof) to determine whether it's just an implicit
> invocation of the trivial default constructor. Fixes PR10034.
>
> Added:
>    cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp   (with props)
> Modified:
>    cfe/trunk/lib/Sema/JumpDiagnostics.cpp
>
> Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=132191&r1=132190&r2=132191&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
> +++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Fri May 27 11:05:29 2011
> @@ -15,6 +15,7 @@
>  #include "clang/Sema/SemaInternal.h"
>  #include "clang/AST/DeclCXX.h"
>  #include "clang/AST/Expr.h"
> +#include "clang/AST/ExprCXX.h"
>  #include "clang/AST/StmtObjC.h"
>  #include "clang/AST/StmtCXX.h"
>  #include "llvm/ADT/BitVector.h"
> @@ -126,18 +127,48 @@
>       InDiag = diag::note_protected_by_cleanup;
>       OutDiag = diag::note_exits_cleanup;
>     } else if (isCPlusPlus) {
> -      // FIXME: In C++0x, we have to check more conditions than "did we
> -      // just give it an initializer?". See 6.7p3.
> -      if (VD->hasLocalStorage() && VD->hasInit())
> -        InDiag = diag::note_protected_by_variable_init;
> -
> -      CanQualType T = VD->getType()->getCanonicalTypeUnqualified();
> +      if (!VD->hasLocalStorage())
> +        return std::make_pair(InDiag, OutDiag);
> +
> +      ASTContext &Context = D->getASTContext();
> +      QualType T = Context.getBaseElementType(VD->getType());
>       if (!T->isDependentType()) {
> -        while (CanQual<ArrayType> AT = T->getAs<ArrayType>())
> -          T = AT->getElementType();
> -        if (CanQual<RecordType> RT = T->getAs<RecordType>())
> -          if (!cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor())
> +        // C++0x [stmt.dcl]p3:
> +        //   A program that jumps from a point where a variable with automatic
> +        //   storage duration is not in scope to a point where it is in scope
> +        //   is ill-formed unless the variable has scalar type, class type with
> +        //   a trivial default constructor and a trivial destructor, a
> +        //   cv-qualified version of one of these types, or an array of one of
> +        //   the preceding types and is declared without an initializer (8.5).
> +        if (VD->hasLocalStorage() && Context.getLangOptions().CPlusPlus) {

Isn't this condition trivially true here?

-Eli

> +          // Check whether this is a C++ class.
> +          CXXRecordDecl *Record = T->getAsCXXRecordDecl();
> +
> +          if (const Expr *Init = VD->getInit()) {
> +            bool CallsTrivialConstructor = false;
> +            if (Record) {
> +              // FIXME: With generalized initializer lists, this may
> +              // classify "X x{};" as having no initializer.
> +              if (const CXXConstructExpr *Construct
> +                                          = dyn_cast<CXXConstructExpr>(Init))
> +                if (const CXXConstructorDecl *Constructor
> +                                                  = Construct->getConstructor())
> +                  if (Constructor->isDefaultConstructor() &&
> +                      ((Context.getLangOptions().CPlusPlus0x &&
> +                        Record->hasTrivialDefaultConstructor()) ||
> +                       (!Context.getLangOptions().CPlusPlus0x &&
> +                        Record->isPOD())))
> +                    CallsTrivialConstructor = true;
> +            }
> +
> +            if (!CallsTrivialConstructor)
> +              InDiag = diag::note_protected_by_variable_init;
> +          }
> +
> +          // Note whether we have a class with a non-trivial destructor.
> +          if (Record && !Record->hasTrivialDestructor())
>             OutDiag = diag::note_exits_dtor;
> +        }
>       }
>     }
>
>
> Added: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp?rev=132191&view=auto
> ==============================================================================
> --- cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp (added)
> +++ cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp Fri May 27 11:05:29 2011
> @@ -0,0 +1,26 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
> +
> +// PR10034
> +struct X {};
> +
> +void exx(X) {}
> +
> +int main(int argc, char **argv)
> +{
> + if (argc > 3)
> +   goto end;
> +
> + X x;
> + X xs[16];
> + exx(x);
> +
> + end:
> +   if (argc > 1) {
> +   for (int i = 0; i < argc; ++i)
> +   {
> +
> +   }
> +   }
> +   return 0;
> +}
>
> Propchange: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp
> ------------------------------------------------------------------------------
>    svn:eol-style = native
>
> Propchange: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp
> ------------------------------------------------------------------------------
>    svn:keywords = Id
>
> Propchange: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp
> ------------------------------------------------------------------------------
>    svn:mime-type = text/plain
>
>
> _______________________________________________
> 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