[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