forked from OSchip/llvm-project
Delay semantic analysis of the C++ names casts when the subexpression is type-dependent or the destination type is dependent.
llvm-svn: 61165
This commit is contained in:
parent
90ba91574a
commit
19b8c4fffa
|
@ -555,7 +555,10 @@ private:
|
|||
public:
|
||||
|
||||
UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
|
||||
: Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
|
||||
: Expr(UnaryOperatorClass, type,
|
||||
input->isTypeDependent() && opc != OffsetOf,
|
||||
input->isValueDependent()),
|
||||
Val(input), Opc(opc), Loc(l) {}
|
||||
|
||||
Opcode getOpcode() const { return Opc; }
|
||||
Expr *getSubExpr() const { return cast<Expr>(Val); }
|
||||
|
|
|
@ -2876,6 +2876,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
|
|||
/// In C++, the operand might be an overloaded function name, in which case
|
||||
/// we allow the '&' but retain the overloaded-function type.
|
||||
QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
||||
if (op->isTypeDependent())
|
||||
return Context.DependentTy;
|
||||
|
||||
if (getLangOptions().C99) {
|
||||
// Implement C99-only parts of addressof rules.
|
||||
if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
|
||||
|
|
|
@ -65,26 +65,34 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
|
|||
SourceRange OpRange(OpLoc, RParenLoc);
|
||||
SourceRange DestRange(LAngleBracketLoc, RAngleBracketLoc);
|
||||
|
||||
// If the type is dependent, we won't do the semantic analysis now.
|
||||
// FIXME: should we check this in a more fine-grained manner?
|
||||
bool TypeDependent = DestType->isDependentType() || Ex->isTypeDependent();
|
||||
|
||||
switch (Kind) {
|
||||
default: assert(0 && "Unknown C++ cast!");
|
||||
|
||||
case tok::kw_const_cast:
|
||||
CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
if (!TypeDependent)
|
||||
CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
return new CXXConstCastExpr(DestType.getNonReferenceType(), Ex,
|
||||
DestType, OpLoc);
|
||||
|
||||
case tok::kw_dynamic_cast:
|
||||
CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
if (!TypeDependent)
|
||||
CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
return new CXXDynamicCastExpr(DestType.getNonReferenceType(), Ex,
|
||||
DestType, OpLoc);
|
||||
|
||||
case tok::kw_reinterpret_cast:
|
||||
CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
if (!TypeDependent)
|
||||
CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange);
|
||||
return new CXXReinterpretCastExpr(DestType.getNonReferenceType(), Ex,
|
||||
DestType, OpLoc);
|
||||
|
||||
case tok::kw_static_cast:
|
||||
CheckStaticCast(*this, Ex, DestType, OpRange);
|
||||
if (!TypeDependent)
|
||||
CheckStaticCast(*this, Ex, DestType, OpRange);
|
||||
return new CXXStaticCastExpr(DestType.getNonReferenceType(), Ex,
|
||||
DestType, OpLoc);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
class X {
|
||||
public:
|
||||
virtual int f();
|
||||
};
|
||||
|
||||
void g(int);
|
||||
|
||||
|
@ -8,6 +12,10 @@ T f(T x) {
|
|||
(void)T(0);
|
||||
(void)(x += 0);
|
||||
(void)(x? x : x);
|
||||
(void)static_cast<int>(x);
|
||||
(void)reinterpret_cast<int>(x);
|
||||
(void)dynamic_cast<X*>(&x);
|
||||
(void)const_cast<int>(x);
|
||||
return g(x);
|
||||
h(x); // h is a dependent name
|
||||
g(1, 1); // expected-error{{too many arguments to function call}}
|
||||
|
|
Loading…
Reference in New Issue