From: Douglas Gregor Date: Thu, 11 Feb 2010 22:55:30 +0000 (+0000) Subject: When we have a dependent direct initializer but not a dependent X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4dffad64c5c7106dc5ac506be94944299c8f7bc3;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95934 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3b0512f63e..00bc453e84 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/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/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 50479a9b81..fa42634a34 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -93,6 +93,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (isa(E)) DiagID = diag::warn_unused_property_expr; + if (const CXXExprWithTemporaries *Temps = dyn_cast(E)) + E = Temps->getSubExpr(); + if (const CXXZeroInitValueExpr *Zero = dyn_cast(E)) { + if (const RecordType *RecordT = Zero->getType()->getAs()) + if (CXXRecordDecl *RecordD = dyn_cast(RecordT->getDecl())) + if (!RecordD->hasTrivialDestructor()) + return; + } + if (const CallExpr *CE = dyn_cast(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/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index 5620248f50..3b5349a5ce 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/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 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 +struct X0 { }; + +template +void test_dependent_init(T *p) { + X0 i(p); + (void)i; +}