Correctly classify T{} as an array temporary if T is an array of class type with nontrivial destructor.

llvm-svn: 174261
This commit is contained in:
Richard Smith 2013-02-02 02:11:36 +00:00
parent 26c777c409
commit 4be2c36921
2 changed files with 21 additions and 15 deletions

View File

@ -34,21 +34,6 @@ static Cl::Kinds ClassifyConditional(ASTContext &Ctx,
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
Cl::Kinds Kind, SourceLocation &Loc);
static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang,
const Expr *E,
ExprValueKind Kind) {
switch (Kind) {
case VK_RValue:
return Lang.CPlusPlus && E->getType()->isRecordType() ?
Cl::CL_ClassTemporary : Cl::CL_PRValue;
case VK_LValue:
return Cl::CL_LValue;
case VK_XValue:
return Cl::CL_XValue;
}
llvm_unreachable("Invalid value category of implicit cast.");
}
Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
assert(!TR->isReferenceType() && "Expressions can't have reference type.");
@ -100,6 +85,20 @@ static Cl::Kinds ClassifyTemporary(QualType T) {
return Cl::CL_PRValue;
}
static Cl::Kinds ClassifyExprValueKind(const LangOptions &Lang,
const Expr *E,
ExprValueKind Kind) {
switch (Kind) {
case VK_RValue:
return Lang.CPlusPlus ? ClassifyTemporary(E->getType()) : Cl::CL_PRValue;
case VK_LValue:
return Cl::CL_LValue;
case VK_XValue:
return Cl::CL_XValue;
}
llvm_unreachable("Invalid value category of implicit cast.");
}
static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
// This function takes the first stab at classifying expressions.
const LangOptions &Lang = Ctx.getLangOpts();

View File

@ -15,8 +15,13 @@ namespace PointerToArrayDecay {
struct Y {
int a[4];
};
struct Z {
int n;
~Z();
};
typedef int A[4];
typedef Z AZ[4];
template<typename T> void consume(T);
struct S { int *p; };
@ -25,11 +30,13 @@ namespace PointerToArrayDecay {
void g1() { int *p = Y{}.a; } // expected-warning{{pointer is initialized by a temporary array}}
void g2() { int *p = A{}; } // expected-warning{{pointer is initialized by a temporary array}}
void g3() { int *p = (A){}; } // expected-warning{{pointer is initialized by a temporary array}}
void g4() { Z *p = AZ{}; } // expected-warning{{pointer is initialized by a temporary array}}
void h0() { consume(Y().a); }
void h1() { consume(Y{}.a); }
void h2() { consume(A{}); }
void h3() { consume((A){}); }
void h4() { consume(AZ{}); }
void i0() { S s = { Y().a }; } // expected-warning{{pointer is initialized by a temporary array}}
void i1() { S s = { Y{}.a }; } // expected-warning{{pointer is initialized by a temporary array}}