// 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
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;
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.
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.
-// 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
};
void test() {
- A();
+ A(); // expected-warning{{expression result unused}}
B(17);
C();
}
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;
+}