]> granicus.if.org Git - clang/commitdiff
When we have a dependent direct initializer but not a dependent
authorDouglas Gregor <dgregor@apple.com>
Thu, 11 Feb 2010 22:55:30 +0000 (22:55 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 11 Feb 2010 22:55:30 +0000 (22:55 +0000)
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

lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaStmt.cpp
test/SemaCXX/warn-unused-variables.cpp

index 3b0512f63e1dbc892d97c02eceeac642daa2c959..00bc453e84086a4a4e9edbc7af28e1548321c7a2 100644 (file)
@@ -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.
index 50479a9b8168eef0b66c8d8b3b019735f204a310..fa42634a3475f3d99c2cc7a4e6b67eb9d07065bb 100644 (file)
@@ -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.
index 5620248f5005f9fe82b18cac0e0a560141f8aed3..3b5349a5ce1bf5c08af9d1731b29d2a64587bfe6 100644 (file)
@@ -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;
+}