Submitted by:
Reviewed by:
Fix two bugs...

- Sema::CheckConditionalOperands(). Needed to move the check for
null pointer constants up to the clause dealing with two pointers types.
The previous code would never get executed.
- Expr::isNullPointerConstant(). This predicate was much too naive...it
should have had a FIXME (my bad). It now deals with "void *" cast expressions.
It still has one major bug...it needs to evaluate the expression to correctly
determine if it is a null pointer constant (e.g. 7-7 should pass).

llvm-svn: 39464
This commit is contained in:
Steve Naroff 2007-05-20 17:54:12 +00:00
parent 812eda8259
commit ada7d4298b
4 changed files with 58 additions and 9 deletions

View File

@ -266,8 +266,32 @@ bool Expr::isConstantExpr(bool isIntConst, SourceLocation &loc) const {
}
}
// C99 6.3.2.3p3: FIXME: If we have an integer constant expression, we need
// to *evaluate* it and test for the value 0. The current code is too
// simplistic...it only allows for the integer literal "0".
// For example, the following is valid code:
//
// void test1() { *(n ? p : (void *)(7-7)) = 1; }
//
bool Expr::isNullPointerConstant() const {
const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(this);
const IntegerLiteral *constant = 0;
switch (getStmtClass()) {
case IntegerLiteralClass:
constant = cast<IntegerLiteral>(this);
break;
case CastExprClass:
const CastExpr *cExpr = cast<CastExpr>(this);
if (const PointerType *p = dyn_cast<PointerType>(cExpr->getDestType())) {
QualType t = p->getPointeeType();
// the type needs to be "void *" (no qualifiers are permitted)
if (!t.getQualifiers() && t->isVoidType())
constant = dyn_cast<IntegerLiteral>(cExpr->getSubExpr());
}
break;
default:
break;
}
if (!constant || constant->getValue() != 0)
return false;
return true;

View File

@ -428,6 +428,11 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
lhptee = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
rhptee = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
if (RHS->isNullPointerConstant()) // C99 6.5.15p3
return lhs;
if (LHS->isNullPointerConstant())
return rhs;
// ignore qualifiers on void (C99 6.5.15p3, clause 6)
if (lhptee.getUnqualifiedType()->isVoidType() &&
(rhptee->isObjectType() || rhptee->isIncompleteType()))
@ -449,10 +454,6 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
}
if (lhs->isVoidType() && rhs->isVoidType()) // C99 6.5.15p3
return lhs;
if (lhs->isPointerType() && RHS->isNullPointerConstant()) // C99 6.5.15p3
return lhs;
if (rhs->isPointerType() && LHS->isNullPointerConstant()) // C99 6.5.15p3
return rhs;
Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
lhs.getAsString(), rhs.getAsString());

View File

@ -428,6 +428,11 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
lhptee = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
rhptee = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
if (RHS->isNullPointerConstant()) // C99 6.5.15p3
return lhs;
if (LHS->isNullPointerConstant())
return rhs;
// ignore qualifiers on void (C99 6.5.15p3, clause 6)
if (lhptee.getUnqualifiedType()->isVoidType() &&
(rhptee->isObjectType() || rhptee->isIncompleteType()))
@ -449,10 +454,6 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
}
if (lhs->isVoidType() && rhs->isVoidType()) // C99 6.5.15p3
return lhs;
if (lhs->isPointerType() && RHS->isNullPointerConstant()) // C99 6.5.15p3
return lhs;
if (rhs->isPointerType() && LHS->isNullPointerConstant()) // C99 6.5.15p3
return rhs;
Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
lhs.getAsString(), rhs.getAsString());

View File

@ -94,6 +94,23 @@
DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildStyle section */
84DE4C220BFFB2D9009E9268 /* Development */ = {
isa = PBXBuildStyle;
buildSettings = {
COPY_PHASE_STRIP = NO;
};
name = Development;
};
84DE4C230BFFB2D9009E9268 /* Deployment */ = {
isa = PBXBuildStyle;
buildSettings = {
COPY_PHASE_STRIP = YES;
};
name = Deployment;
};
/* End PBXBuildStyle section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@ -476,6 +493,12 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
buildSettings = {
};
buildStyles = (
84DE4C220BFFB2D9009E9268 /* Development */,
84DE4C230BFFB2D9009E9268 /* Deployment */,
);
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";