зеркало из https://github.com/microsoft/clang-1.git
Detect operator-> chains of arbitrary length. Use a terrible data structure
to strike fear into the hearts of CPUs everywhere. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83133 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4a4e345a8b
Коммит
c4e8321deb
|
@ -1977,17 +1977,23 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
// [...] When operator->returns, the operator-> is applied to the value
|
||||
// returned, with the original second operand.
|
||||
if (OpKind == tok::arrow) {
|
||||
// The set of types we've considered so far.
|
||||
llvm::SmallVector<CanQualType,8> CTypes;
|
||||
CTypes.push_back(Context.getCanonicalType(BaseType));
|
||||
|
||||
while (BaseType->isRecordType()) {
|
||||
Base = BuildOverloadedArrowExpr(S, move(Base), BaseExpr->getExprLoc());
|
||||
BaseExpr = (Expr*)Base.get();
|
||||
if (BaseExpr == NULL)
|
||||
return ExprError();
|
||||
if (Context.getCanonicalType(BaseExpr->getType()) ==
|
||||
Context.getCanonicalType(BaseType)) {
|
||||
BaseType = BaseExpr->getType();
|
||||
CanQualType CBaseType = Context.getCanonicalType(BaseType);
|
||||
if (std::find(CTypes.begin(), CTypes.end(), CBaseType) != CTypes.end()) {
|
||||
// TODO: note the chain of conversions
|
||||
Diag(OpLoc, diag::err_operator_arrow_circular);
|
||||
return ExprError();
|
||||
}
|
||||
BaseType = BaseExpr->getType();
|
||||
CTypes.push_back(CBaseType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,3 +224,19 @@ void m() {
|
|||
AX a;
|
||||
a->b = 0; // expected-error {{circular pointer delegation detected}}
|
||||
}
|
||||
|
||||
struct CircA {
|
||||
struct CircB& operator->();
|
||||
int val;
|
||||
};
|
||||
struct CircB {
|
||||
struct CircC& operator->();
|
||||
};
|
||||
struct CircC {
|
||||
struct CircA& operator->();
|
||||
};
|
||||
|
||||
void circ() {
|
||||
CircA a;
|
||||
a->val = 0; // expected-error {{circular pointer delegation detected}}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче