зеркало из https://github.com/microsoft/clang-1.git
Add proper type-checking for pointer additiion; before, we were accepting
addition with a pointer and an integer even when it didn't make sense. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51228 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
316bb1b9eb
Коммит
d72d16e6f1
|
@ -1405,15 +1405,33 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
|
|||
return CheckVectorOperands(loc, lex, rex);
|
||||
|
||||
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
|
||||
|
||||
|
||||
// handle the common case first (both operands are arithmetic).
|
||||
if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
|
||||
return compType;
|
||||
|
||||
if (lex->getType()->isPointerType() && rex->getType()->isIntegerType())
|
||||
return lex->getType();
|
||||
if (lex->getType()->isIntegerType() && rex->getType()->isPointerType())
|
||||
return rex->getType();
|
||||
// Put any potential pointer into PExp
|
||||
Expr* PExp = lex, *IExp = rex;
|
||||
if (IExp->getType()->isPointerType())
|
||||
std::swap(PExp, IExp);
|
||||
|
||||
if (const PointerType* PTy = PExp->getType()->getAsPointerType()) {
|
||||
if (IExp->getType()->isIntegerType()) {
|
||||
// Check for arithmetic on pointers to incomplete types
|
||||
if (!PTy->getPointeeType()->isObjectType()) {
|
||||
if (PTy->getPointeeType()->isVoidType()) {
|
||||
Diag(loc, diag::ext_gnu_void_ptr,
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
} else {
|
||||
Diag(loc, diag::err_typecheck_arithmetic_incomplete_type,
|
||||
lex->getType().getAsString(), lex->getSourceRange());
|
||||
return QualType();
|
||||
}
|
||||
}
|
||||
return PExp->getType();
|
||||
}
|
||||
}
|
||||
|
||||
return InvalidOperands(loc, lex, rex);
|
||||
}
|
||||
|
||||
|
@ -1681,7 +1699,10 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) {
|
|||
|
||||
// C99 6.5.2.4p1: We allow complex as a GCC extension.
|
||||
if (const PointerType *pt = resType->getAsPointerType()) {
|
||||
if (!pt->getPointeeType()->isObjectType()) { // C99 6.5.2.4p2, 6.5.6p2
|
||||
if (pt->getPointeeType()->isVoidType()) {
|
||||
Diag(OpLoc, diag::ext_gnu_void_ptr, op->getSourceRange());
|
||||
} else if (!pt->getPointeeType()->isObjectType()) {
|
||||
// C99 6.5.2.4p2, 6.5.6p2
|
||||
Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type,
|
||||
resType.getAsString(), op->getSourceRange());
|
||||
return QualType();
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: clang %s -fsyntax-only -verify -pedantic
|
||||
|
||||
typedef struct S S;
|
||||
void a(S* b, void* c) {
|
||||
b++; // expected-error {{arithmetic on pointer to incomplete type}}
|
||||
b += 1; // expected-error {{arithmetic on pointer to incomplete type}}
|
||||
c++; // expected-warning {{use of GNU void* extension}}
|
||||
c += 1; // expected-warning {{use of GNU void* extension}}
|
||||
b = 1+b; // expected-error {{arithmetic on pointer to incomplete type}}
|
||||
/* The next couple tests are only pedantic warnings in gcc */
|
||||
void (*d)(S*,void*) = a;
|
||||
d += 1; // expected-error {{pointer to incomplete type}}
|
||||
d++; // expected-error {{pointer to incomplete type}}
|
||||
}
|
Загрузка…
Ссылка в новой задаче