forked from OSchip/llvm-project
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:
parent
26c777c409
commit
4be2c36921
|
@ -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();
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue