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);
|
||||
/// \endcode
|
||||
class CXXFunctionalCastExpr : public ExplicitCastExpr {
|
||||
SourceLocation TyBeginLoc;
|
||||
SourceLocation LParenLoc;
|
||||
SourceLocation RParenLoc;
|
||||
|
||||
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
|
||||
TypeSourceInfo *writtenTy,
|
||||
SourceLocation tyBeginLoc, CastKind kind,
|
||||
Expr *castExpr, unsigned pathSize,
|
||||
SourceLocation rParenLoc)
|
||||
CastKind kind, Expr *castExpr, unsigned pathSize,
|
||||
SourceLocation lParenLoc, SourceLocation rParenLoc)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
|
||||
castExpr, pathSize, writtenTy),
|
||||
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
|
||||
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
|
||||
|
||||
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
|
||||
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
|
||||
|
@ -1225,22 +1224,20 @@ public:
|
|||
static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
|
||||
ExprValueKind VK,
|
||||
TypeSourceInfo *Written,
|
||||
SourceLocation TyBeginLoc,
|
||||
CastKind Kind, Expr *Op,
|
||||
const CXXCastPath *Path,
|
||||
SourceLocation LPLoc,
|
||||
SourceLocation RPLoc);
|
||||
static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
|
||||
unsigned PathSize);
|
||||
|
||||
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
|
||||
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
|
||||
}
|
||||
SourceLocation getLocStart() const LLVM_READONLY;
|
||||
SourceLocation getLocEnd() const LLVM_READONLY;
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXFunctionalCastExprClass;
|
||||
|
|
|
@ -2177,7 +2177,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
|
|||
WarnE = this;
|
||||
if (const CXXFunctionalCastExpr *CXXCE =
|
||||
dyn_cast<CXXFunctionalCastExpr>(this)) {
|
||||
Loc = CXXCE->getTypeBeginLoc();
|
||||
Loc = CXXCE->getLocStart();
|
||||
R1 = CXXCE->getSubExpr()->getSourceRange();
|
||||
} else {
|
||||
const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
|
||||
|
|
|
@ -660,14 +660,14 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
|
|||
|
||||
CXXFunctionalCastExpr *
|
||||
CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
|
||||
TypeSourceInfo *Written, SourceLocation L,
|
||||
CastKind K, Expr *Op, const CXXCastPath *BasePath,
|
||||
SourceLocation R) {
|
||||
TypeSourceInfo *Written, CastKind K, Expr *Op,
|
||||
const CXXCastPath *BasePath,
|
||||
SourceLocation L, SourceLocation R) {
|
||||
unsigned PathSize = (BasePath ? BasePath->size() : 0);
|
||||
void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
|
||||
+ PathSize * sizeof(CXXBaseSpecifier*));
|
||||
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);
|
||||
return E;
|
||||
}
|
||||
|
@ -679,6 +679,14 @@ CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned 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::getLiteralOperatorKind() const {
|
||||
if (getNumArgs() == 0)
|
||||
|
|
|
@ -227,7 +227,7 @@ static SourceLocation GetUnreachableLoc(const Stmt *S,
|
|||
case Expr::CXXFunctionalCastExprClass: {
|
||||
const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
|
||||
R1 = CE->getSubExpr()->getSourceRange();
|
||||
return CE->getTypeBeginLoc();
|
||||
return CE->getLocStart();
|
||||
}
|
||||
case Stmt::CXXTryStmtClass: {
|
||||
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
|
||||
|
|
|
@ -2364,6 +2364,6 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
|
|||
ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc));
|
||||
|
||||
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
|
||||
Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
|
||||
Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
|
||||
Op.ValueKind, CastTypeInfo, Op.Kind,
|
||||
Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
|
||||
}
|
||||
|
|
|
@ -902,8 +902,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
|||
InitListExpr *List = cast<InitListExpr>(Result.take());
|
||||
Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
|
||||
Expr::getValueKindForType(TInfo->getType()),
|
||||
TInfo, TyBeginLoc, CK_NoOp,
|
||||
List, /*Path=*/0, RParenLoc));
|
||||
TInfo, CK_NoOp, List,
|
||||
/*Path=*/0,
|
||||
LParenLoc, RParenLoc));
|
||||
}
|
||||
|
||||
// FIXME: Improve AST representation?
|
||||
|
|
|
@ -7317,7 +7317,7 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
|
|||
return SemaRef.Owned(E);
|
||||
|
||||
return getDerived().RebuildCXXFunctionalCastExpr(Type,
|
||||
/*FIXME:*/E->getSubExpr()->getLocStart(),
|
||||
E->getLParenLoc(),
|
||||
SubExpr.get(),
|
||||
E->getRParenLoc());
|
||||
}
|
||||
|
|
|
@ -1263,7 +1263,7 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
|||
|
||||
void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
||||
VisitExplicitCastExpr(E);
|
||||
E->setTypeBeginLoc(ReadSourceLocation(Record, Idx));
|
||||
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
||||
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
||||
}
|
||||
|
||||
|
|
|
@ -1226,7 +1226,7 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
|||
|
||||
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
||||
VisitExplicitCastExpr(E);
|
||||
Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
|
||||
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
||||
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
||||
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
||||
}
|
||||
|
|
|
@ -118,3 +118,18 @@ namespace PR13064 {
|
|||
template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
|
||||
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