diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-02-11 22:55:30 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-02-11 22:55:30 +0000 |
commit | 50dc219e8b1ca70a9b92aa3486c047636115cb27 (patch) | |
tree | 8d342ffc8956e4d7d86297dd655b22ad2b8230a1 | |
parent | 9d6eb40ce7c28d4a0715c8699070ea2be41f40f7 (diff) | |
download | bcm5719-llvm-50dc219e8b1ca70a9b92aa3486c047636115cb27.tar.gz bcm5719-llvm-50dc219e8b1ca70a9b92aa3486c047636115cb27.zip |
When we have a dependent direct initializer but not a dependent
variable type, we can (and should) still check for completeness of the
variable's type. Do so, to work around an assertion that shows up in
Boost's shared_ptr.
llvm-svn: 95934
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 36 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unused-variables.cpp | 18 |
3 files changed, 40 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3b0512f63e1..00bc453e840 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4038,23 +4038,6 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, // exactly form was it (like the CodeGen) can handle both cases without // special case code. - // If either the declaration has a dependent type or if any of the expressions - // is type-dependent, we represent the initialization via a ParenListExpr for - // later use during template instantiation. - if (VDecl->getType()->isDependentType() || - Expr::hasAnyTypeDependentArguments((Expr **)Exprs.get(), Exprs.size())) { - // Let clients know that initialization was done with a direct initializer. - VDecl->setCXXDirectInitializer(true); - - // Store the initialization expressions as a ParenListExpr. - unsigned NumExprs = Exprs.size(); - VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc, - (Expr **)Exprs.release(), - NumExprs, RParenLoc)); - return; - } - - // C++ 8.5p11: // The form of initialization (using parentheses or '=') is generally // insignificant, but does matter when the entity being initialized has a @@ -4063,7 +4046,8 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, if (const ArrayType *Array = Context.getAsArrayType(DeclInitType)) DeclInitType = Context.getBaseElementType(Array); - if (RequireCompleteType(VDecl->getLocation(), VDecl->getType(), + if (!VDecl->getType()->isDependentType() && + RequireCompleteType(VDecl->getLocation(), VDecl->getType(), diag::err_typecheck_decl_incomplete_type)) { VDecl->setInvalidDecl(); return; @@ -4083,6 +4067,22 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, VDecl->setInvalidDecl(); return; } + + // If either the declaration has a dependent type or if any of the + // expressions is type-dependent, we represent the initialization + // via a ParenListExpr for later use during template instantiation. + if (VDecl->getType()->isDependentType() || + Expr::hasAnyTypeDependentArguments((Expr **)Exprs.get(), Exprs.size())) { + // Let clients know that initialization was done with a direct initializer. + VDecl->setCXXDirectInitializer(true); + + // Store the initialization expressions as a ParenListExpr. + unsigned NumExprs = Exprs.size(); + VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc, + (Expr **)Exprs.release(), + NumExprs, RParenLoc)); + return; + } // Capture the variable that is being initialized and the style of // initialization. diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 50479a9b816..fa42634a347 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -93,6 +93,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (isa<ObjCImplicitSetterGetterRefExpr>(E)) DiagID = diag::warn_unused_property_expr; + if (const CXXExprWithTemporaries *Temps = dyn_cast<CXXExprWithTemporaries>(E)) + E = Temps->getSubExpr(); + if (const CXXZeroInitValueExpr *Zero = dyn_cast<CXXZeroInitValueExpr>(E)) { + if (const RecordType *RecordT = Zero->getType()->getAs<RecordType>()) + if (CXXRecordDecl *RecordD = dyn_cast<CXXRecordDecl>(RecordT->getDecl())) + if (!RecordD->hasTrivialDestructor()) + return; + } + if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { // If the callee has attribute pure, const, or warn_unused_result, warn with // a more specific message to make it clear what is happening. diff --git a/clang/test/SemaCXX/warn-unused-variables.cpp b/clang/test/SemaCXX/warn-unused-variables.cpp index 5620248f500..3b5349a5ce1 100644 --- a/clang/test/SemaCXX/warn-unused-variables.cpp +++ b/clang/test/SemaCXX/warn-unused-variables.cpp @@ -1,8 +1,7 @@ -// RUN: %clang -fsyntax-only -Wunused-variable -verify %s - +// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s template<typename T> void f() { - T t; - t = 17; + T t; + t = 17; } // PR5407 @@ -27,7 +26,7 @@ namespace PR5531 { }; void test() { - A(); + A(); // expected-warning{{expression result unused}} B(17); C(); } @@ -43,3 +42,12 @@ void bah() { x.foo(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} x2->foo(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} } + +template<typename T> +struct X0 { }; + +template<typename T> +void test_dependent_init(T *p) { + X0<int> i(p); + (void)i; +} |