forked from OSchip/llvm-project
Properly track l-paren of a CXXFucntionalCastExpr.
In addition to storing more useful information in the AST, this fixes a semantic check in template instantiation which checks whether the l-paren location is valid. Fixes PR16903. llvm-svn: 188495
This commit is contained in:
parent
35b22f6985
commit
89fe0d5842
|
@ -1206,17 +1206,16 @@ public:
|
||||||
/// x = int(0.5);
|
/// x = int(0.5);
|
||||||
/// \endcode
|
/// \endcode
|
||||||
class CXXFunctionalCastExpr : public ExplicitCastExpr {
|
class CXXFunctionalCastExpr : public ExplicitCastExpr {
|
||||||
SourceLocation TyBeginLoc;
|
SourceLocation LParenLoc;
|
||||||
SourceLocation RParenLoc;
|
SourceLocation RParenLoc;
|
||||||
|
|
||||||
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
|
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
|
||||||
TypeSourceInfo *writtenTy,
|
TypeSourceInfo *writtenTy,
|
||||||
SourceLocation tyBeginLoc, CastKind kind,
|
CastKind kind, Expr *castExpr, unsigned pathSize,
|
||||||
Expr *castExpr, unsigned pathSize,
|
SourceLocation lParenLoc, SourceLocation rParenLoc)
|
||||||
SourceLocation rParenLoc)
|
|
||||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
|
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
|
||||||
castExpr, pathSize, writtenTy),
|
castExpr, pathSize, writtenTy),
|
||||||
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
|
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
|
||||||
|
|
||||||
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
|
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
|
||||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
|
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
|
||||||
|
@ -1225,22 +1224,20 @@ public:
|
||||||
static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
|
static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
|
||||||
ExprValueKind VK,
|
ExprValueKind VK,
|
||||||
TypeSourceInfo *Written,
|
TypeSourceInfo *Written,
|
||||||
SourceLocation TyBeginLoc,
|
|
||||||
CastKind Kind, Expr *Op,
|
CastKind Kind, Expr *Op,
|
||||||
const CXXCastPath *Path,
|
const CXXCastPath *Path,
|
||||||
|
SourceLocation LPLoc,
|
||||||
SourceLocation RPLoc);
|
SourceLocation RPLoc);
|
||||||
static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
|
static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
|
||||||
unsigned PathSize);
|
unsigned PathSize);
|
||||||
|
|
||||||
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
|
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||||
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
|
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||||
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
|
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
|
||||||
|
|
||||||
SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
|
SourceLocation getLocStart() const LLVM_READONLY;
|
||||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
SourceLocation getLocEnd() const LLVM_READONLY;
|
||||||
return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool classof(const Stmt *T) {
|
static bool classof(const Stmt *T) {
|
||||||
return T->getStmtClass() == CXXFunctionalCastExprClass;
|
return T->getStmtClass() == CXXFunctionalCastExprClass;
|
||||||
|
|
|
@ -2177,7 +2177,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
|
||||||
WarnE = this;
|
WarnE = this;
|
||||||
if (const CXXFunctionalCastExpr *CXXCE =
|
if (const CXXFunctionalCastExpr *CXXCE =
|
||||||
dyn_cast<CXXFunctionalCastExpr>(this)) {
|
dyn_cast<CXXFunctionalCastExpr>(this)) {
|
||||||
Loc = CXXCE->getTypeBeginLoc();
|
Loc = CXXCE->getLocStart();
|
||||||
R1 = CXXCE->getSubExpr()->getSourceRange();
|
R1 = CXXCE->getSubExpr()->getSourceRange();
|
||||||
} else {
|
} else {
|
||||||
const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
|
const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
|
||||||
|
|
|
@ -660,14 +660,14 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
|
||||||
|
|
||||||
CXXFunctionalCastExpr *
|
CXXFunctionalCastExpr *
|
||||||
CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
|
CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
|
||||||
TypeSourceInfo *Written, SourceLocation L,
|
TypeSourceInfo *Written, CastKind K, Expr *Op,
|
||||||
CastKind K, Expr *Op, const CXXCastPath *BasePath,
|
const CXXCastPath *BasePath,
|
||||||
SourceLocation R) {
|
SourceLocation L, SourceLocation R) {
|
||||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||||
void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
|
void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
|
||||||
+ PathSize * sizeof(CXXBaseSpecifier*));
|
+ PathSize * sizeof(CXXBaseSpecifier*));
|
||||||
CXXFunctionalCastExpr *E =
|
CXXFunctionalCastExpr *E =
|
||||||
new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R);
|
new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
|
||||||
if (PathSize) E->setCastPath(*BasePath);
|
if (PathSize) E->setCastPath(*BasePath);
|
||||||
return E;
|
return E;
|
||||||
}
|
}
|
||||||
|
@ -679,6 +679,14 @@ CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
|
||||||
return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
|
return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourceLocation CXXFunctionalCastExpr::getLocStart() const {
|
||||||
|
return getTypeInfoAsWritten()->getTypeLoc().getLocStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceLocation CXXFunctionalCastExpr::getLocEnd() const {
|
||||||
|
return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
|
||||||
|
}
|
||||||
|
|
||||||
UserDefinedLiteral::LiteralOperatorKind
|
UserDefinedLiteral::LiteralOperatorKind
|
||||||
UserDefinedLiteral::getLiteralOperatorKind() const {
|
UserDefinedLiteral::getLiteralOperatorKind() const {
|
||||||
if (getNumArgs() == 0)
|
if (getNumArgs() == 0)
|
||||||
|
|
|
@ -227,7 +227,7 @@ static SourceLocation GetUnreachableLoc(const Stmt *S,
|
||||||
case Expr::CXXFunctionalCastExprClass: {
|
case Expr::CXXFunctionalCastExprClass: {
|
||||||
const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
|
const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
|
||||||
R1 = CE->getSubExpr()->getSourceRange();
|
R1 = CE->getSubExpr()->getSourceRange();
|
||||||
return CE->getTypeBeginLoc();
|
return CE->getLocStart();
|
||||||
}
|
}
|
||||||
case Stmt::CXXTryStmtClass: {
|
case Stmt::CXXTryStmtClass: {
|
||||||
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
|
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
|
||||||
|
|
|
@ -2364,6 +2364,6 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
|
||||||
ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc));
|
ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc));
|
||||||
|
|
||||||
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
|
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
|
||||||
Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
|
Op.ValueKind, CastTypeInfo, Op.Kind,
|
||||||
Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
|
Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -902,8 +902,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
||||||
InitListExpr *List = cast<InitListExpr>(Result.take());
|
InitListExpr *List = cast<InitListExpr>(Result.take());
|
||||||
Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
|
Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
|
||||||
Expr::getValueKindForType(TInfo->getType()),
|
Expr::getValueKindForType(TInfo->getType()),
|
||||||
TInfo, TyBeginLoc, CK_NoOp,
|
TInfo, CK_NoOp, List,
|
||||||
List, /*Path=*/0, RParenLoc));
|
/*Path=*/0,
|
||||||
|
LParenLoc, RParenLoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Improve AST representation?
|
// FIXME: Improve AST representation?
|
||||||
|
|
|
@ -7317,7 +7317,7 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
|
||||||
return SemaRef.Owned(E);
|
return SemaRef.Owned(E);
|
||||||
|
|
||||||
return getDerived().RebuildCXXFunctionalCastExpr(Type,
|
return getDerived().RebuildCXXFunctionalCastExpr(Type,
|
||||||
/*FIXME:*/E->getSubExpr()->getLocStart(),
|
E->getLParenLoc(),
|
||||||
SubExpr.get(),
|
SubExpr.get(),
|
||||||
E->getRParenLoc());
|
E->getRParenLoc());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1263,7 +1263,7 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
||||||
|
|
||||||
void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
||||||
VisitExplicitCastExpr(E);
|
VisitExplicitCastExpr(E);
|
||||||
E->setTypeBeginLoc(ReadSourceLocation(Record, Idx));
|
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
||||||
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1226,7 +1226,7 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
||||||
|
|
||||||
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
||||||
VisitExplicitCastExpr(E);
|
VisitExplicitCastExpr(E);
|
||||||
Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
||||||
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
||||||
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,3 +118,18 @@ namespace PR13064 {
|
||||||
template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
|
template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
|
||||||
C<A> c; // expected-note{{here}}
|
C<A> c; // expected-note{{here}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PR16903 {
|
||||||
|
// Make sure we properly instantiate list-initialization.
|
||||||
|
template<typename T>
|
||||||
|
void fun (T it) {
|
||||||
|
int m = 0;
|
||||||
|
for (int i = 0; i < 4; ++i, ++it){
|
||||||
|
m |= long{char{*it}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int test() {
|
||||||
|
char in[4] = {0,0,0,0};
|
||||||
|
fun(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue