Bug #:
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:
parent
812eda8259
commit
ada7d4298b
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
Loading…
Reference in New Issue