Skip to content

Commit a65e1f3

Browse files
committed
Move promoteExprToType from being a static method in SemaExpr.cpp to being
a method named ImpCastExprToType in Sema. Use this method to insert implicit casts for case statements from their operand type to the condition type of the switch. This fixes a crash on test/CodeGen/statements.c, reported by Eli Friedman. llvm-svn: 46083
1 parent 45b985c commit a65e1f3

File tree

5 files changed

+77
-47
lines changed

5 files changed

+77
-47
lines changed

clang/Sema/Sema.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt)
120120
TUScope = 0;
121121
}
122122

123+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
124+
/// If there is already an implicit cast, merge into the existing one.
125+
void Sema::ImpCastExprToType(Expr *&Expr, QualType Type) {
126+
if (Expr->getType() == Type) return;
127+
128+
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr))
129+
ImpCast->setType(Type);
130+
else
131+
Expr = new ImplicitCastExpr(Type, Expr);
132+
}
133+
134+
135+
123136
void Sema::DeleteExpr(ExprTy *E) {
124137
delete static_cast<Expr*>(E);
125138
}

clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,10 @@ class Sema : public Action {
596596
SourceLocation lbrac, SourceLocation rbrac,
597597
ExprTy **ArgExprs, unsigned NumArgs);
598598
private:
599+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
600+
/// cast. If there is already an implicit cast, merge into the existing one.
601+
void ImpCastExprToType(Expr *&Expr, QualType Type);
602+
599603
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
600604
// functions and arrays to their respective pointers (C99 6.3.2.1).
601605
Expr *UsualUnaryConversions(Expr *&expr);

clang/Sema/SemaExpr.cpp

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -750,16 +750,6 @@ ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
750750
return new CastExpr(castType, castExpr, LParenLoc);
751751
}
752752

753-
// promoteExprToType - a helper function to ensure we create exactly one
754-
// ImplicitCastExpr.
755-
static void promoteExprToType(Expr *&expr, QualType type) {
756-
if (ImplicitCastExpr *impCast = dyn_cast<ImplicitCastExpr>(expr))
757-
impCast->setType(type);
758-
else
759-
expr = new ImplicitCastExpr(type, expr);
760-
return;
761-
}
762-
763753
/// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
764754
/// In that case, lex = cond.
765755
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
@@ -804,11 +794,11 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
804794
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
805795
// the type of the other operand."
806796
if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) {
807-
promoteExprToType(rex, lexT); // promote the null to a pointer.
797+
ImpCastExprToType(rex, lexT); // promote the null to a pointer.
808798
return lexT;
809799
}
810800
if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) {
811-
promoteExprToType(lex, rexT); // promote the null to a pointer.
801+
ImpCastExprToType(lex, rexT); // promote the null to a pointer.
812802
return rexT;
813803
}
814804
// Handle the case where both operands are pointers before we handle null
@@ -882,9 +872,9 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
882872
assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
883873

884874
if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2
885-
promoteExprToType(Expr, Context.IntTy);
875+
ImpCastExprToType(Expr, Context.IntTy);
886876
if (Ty == Context.FloatTy)
887-
promoteExprToType(Expr, Context.DoubleTy);
877+
ImpCastExprToType(Expr, Context.DoubleTy);
888878
}
889879

890880
/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
@@ -893,13 +883,13 @@ void Sema::DefaultFunctionArrayConversion(Expr *&e) {
893883
assert(!t.isNull() && "DefaultFunctionArrayConversion - missing type");
894884

895885
if (const ReferenceType *ref = t->getAsReferenceType()) {
896-
promoteExprToType(e, ref->getReferenceeType()); // C++ [expr]
886+
ImpCastExprToType(e, ref->getReferenceeType()); // C++ [expr]
897887
t = e->getType();
898888
}
899889
if (t->isFunctionType())
900-
promoteExprToType(e, Context.getPointerType(t));
890+
ImpCastExprToType(e, Context.getPointerType(t));
901891
else if (const ArrayType *ary = t->getAsArrayType())
902-
promoteExprToType(e, Context.getPointerType(ary->getElementType()));
892+
ImpCastExprToType(e, Context.getPointerType(ary->getElementType()));
903893
}
904894

905895
/// UsualUnaryConversion - Performs various conversions that are common to most
@@ -912,11 +902,11 @@ Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
912902
assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
913903

914904
if (const ReferenceType *Ref = Ty->getAsReferenceType()) {
915-
promoteExprToType(Expr, Ref->getReferenceeType()); // C++ [expr]
905+
ImpCastExprToType(Expr, Ref->getReferenceeType()); // C++ [expr]
916906
Ty = Expr->getType();
917907
}
918908
if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2
919-
promoteExprToType(Expr, Context.IntTy);
909+
ImpCastExprToType(Expr, Context.IntTy);
920910
else
921911
DefaultFunctionArrayConversion(Expr);
922912

@@ -955,12 +945,12 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
955945
// if we have an integer operand, the result is the complex type.
956946
if (rhs->isIntegerType() || rhs->isComplexIntegerType()) {
957947
// convert the rhs to the lhs complex type.
958-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
948+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
959949
return lhs;
960950
}
961951
if (lhs->isIntegerType() || lhs->isComplexIntegerType()) {
962952
// convert the lhs to the rhs complex type.
963-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
953+
if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
964954
return rhs;
965955
}
966956
// This handles complex/complex, complex/float, or float/complex.
@@ -978,23 +968,23 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
978968
if (result > 0) { // The left side is bigger, convert rhs.
979969
rhs = Context.getFloatingTypeOfSizeWithinDomain(lhs, rhs);
980970
if (!isCompAssign)
981-
promoteExprToType(rhsExpr, rhs);
971+
ImpCastExprToType(rhsExpr, rhs);
982972
} else if (result < 0) { // The right side is bigger, convert lhs.
983973
lhs = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs);
984974
if (!isCompAssign)
985-
promoteExprToType(lhsExpr, lhs);
975+
ImpCastExprToType(lhsExpr, lhs);
986976
}
987977
// At this point, lhs and rhs have the same rank/size. Now, make sure the
988978
// domains match. This is a requirement for our implementation, C99
989979
// does not require this promotion.
990980
if (lhs != rhs) { // Domains don't match, we have complex/float mix.
991981
if (lhs->isRealFloatingType()) { // handle "double, _Complex double".
992982
if (!isCompAssign)
993-
promoteExprToType(lhsExpr, rhs);
983+
ImpCastExprToType(lhsExpr, rhs);
994984
return rhs;
995985
} else { // handle "_Complex double, double".
996986
if (!isCompAssign)
997-
promoteExprToType(rhsExpr, lhs);
987+
ImpCastExprToType(rhsExpr, lhs);
998988
return lhs;
999989
}
1000990
}
@@ -1005,24 +995,24 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
1005995
// if we have an integer operand, the result is the real floating type.
1006996
if (rhs->isIntegerType() || rhs->isComplexIntegerType()) {
1007997
// convert rhs to the lhs floating point type.
1008-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
998+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
1009999
return lhs;
10101000
}
10111001
if (lhs->isIntegerType() || lhs->isComplexIntegerType()) {
10121002
// convert lhs to the rhs floating point type.
1013-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
1003+
if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
10141004
return rhs;
10151005
}
10161006
// We have two real floating types, float/complex combos were handled above.
10171007
// Convert the smaller operand to the bigger result.
10181008
int result = Context.compareFloatingType(lhs, rhs);
10191009

10201010
if (result > 0) { // convert the rhs
1021-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
1011+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
10221012
return lhs;
10231013
}
10241014
if (result < 0) { // convert the lhs
1025-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
1015+
if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
10261016
return rhs;
10271017
}
10281018
assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison");
@@ -1034,28 +1024,30 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
10341024

10351025
if (lhsComplexInt && rhsComplexInt) {
10361026
if (Context.maxIntegerType(lhsComplexInt->getElementType(),
1037-
rhsComplexInt->getElementType()) == lhs) {
1038-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs); // convert the rhs
1039-
return lhs;
1027+
rhsComplexInt->getElementType()) == lhs) {
1028+
// convert the rhs
1029+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
1030+
return lhs;
10401031
}
1041-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
1032+
if (!isCompAssign)
1033+
ImpCastExprToType(lhsExpr, rhs); // convert the lhs
10421034
return rhs;
10431035
} else if (lhsComplexInt && rhs->isIntegerType()) {
10441036
// convert the rhs to the lhs complex type.
1045-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
1037+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
10461038
return lhs;
10471039
} else if (rhsComplexInt && lhs->isIntegerType()) {
10481040
// convert the lhs to the rhs complex type.
1049-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
1041+
if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
10501042
return rhs;
10511043
}
10521044
}
10531045
// Finally, we have two differing integer types.
10541046
if (Context.maxIntegerType(lhs, rhs) == lhs) { // convert the rhs
1055-
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
1047+
if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
10561048
return lhs;
10571049
}
1058-
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
1050+
if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
10591051
return rhs;
10601052
}
10611053

@@ -1212,7 +1204,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
12121204
// a null pointer constant.
12131205
if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType())
12141206
&& rExpr->isNullPointerConstant(Context)) {
1215-
promoteExprToType(rExpr, lhsType);
1207+
ImpCastExprToType(rExpr, lhsType);
12161208
return Compatible;
12171209
}
12181210
// This check seems unnatural, however it is necessary to ensure the proper
@@ -1231,7 +1223,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
12311223
// C99 6.5.16.1p2: The value of the right operand is converted to the
12321224
// type of the assignment expression.
12331225
if (rExpr->getType() != lhsType)
1234-
promoteExprToType(rExpr, lhsType);
1226+
ImpCastExprToType(rExpr, lhsType);
12351227
return result;
12361228
}
12371229

@@ -1260,7 +1252,7 @@ inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex,
12601252
if (const OCUVectorType *V = lhsType->getAsOCUVectorType()) {
12611253
if (V->getElementType().getCanonicalType().getTypePtr()
12621254
== rhsType.getCanonicalType().getTypePtr()) {
1263-
promoteExprToType(rex, lhsType);
1255+
ImpCastExprToType(rex, lhsType);
12641256
return lhsType;
12651257
}
12661258
}
@@ -1270,7 +1262,7 @@ inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex,
12701262
if (const OCUVectorType *V = rhsType->getAsOCUVectorType()) {
12711263
if (V->getElementType().getCanonicalType().getTypePtr()
12721264
== lhsType.getCanonicalType().getTypePtr()) {
1273-
promoteExprToType(lex, rhsType);
1265+
ImpCastExprToType(lex, rhsType);
12741266
return rhsType;
12751267
}
12761268
}
@@ -1463,28 +1455,28 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8
14631455
lType.getAsString(), rType.getAsString(),
14641456
lex->getSourceRange(), rex->getSourceRange());
14651457
}
1466-
promoteExprToType(rex, lType); // promote the pointer to pointer
1458+
ImpCastExprToType(rex, lType); // promote the pointer to pointer
14671459
return Context.IntTy;
14681460
}
14691461
if ((lType->isObjCQualifiedIdType() || rType->isObjCQualifiedIdType())
14701462
&& Context.ObjCQualifiedIdTypesAreCompatible(lType, rType, true)) {
1471-
promoteExprToType(rex, lType);
1463+
ImpCastExprToType(rex, lType);
14721464
return Context.IntTy;
14731465
}
14741466
if (lType->isPointerType() && rType->isIntegerType()) {
14751467
if (!RHSIsNull)
14761468
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
14771469
lType.getAsString(), rType.getAsString(),
14781470
lex->getSourceRange(), rex->getSourceRange());
1479-
promoteExprToType(rex, lType); // promote the integer to pointer
1471+
ImpCastExprToType(rex, lType); // promote the integer to pointer
14801472
return Context.IntTy;
14811473
}
14821474
if (lType->isIntegerType() && rType->isPointerType()) {
14831475
if (!LHSIsNull)
14841476
Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
14851477
lType.getAsString(), rType.getAsString(),
14861478
lex->getSourceRange(), rex->getSourceRange());
1487-
promoteExprToType(lex, rType); // promote the integer to pointer
1479+
ImpCastExprToType(lex, rType); // promote the integer to pointer
14881480
return Context.IntTy;
14891481
}
14901482
return InvalidOperands(loc, lex, rex);

clang/Sema/SemaStmt.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,19 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch,
346346
// We already verified that the expression has a i-c-e value (C99
347347
// 6.8.4.2p3) - get that value now.
348348
llvm::APSInt LoVal(32);
349-
CS->getLHS()->isIntegerConstantExpr(LoVal, Context);
349+
Expr *Lo = CS->getLHS();
350+
Lo->isIntegerConstantExpr(LoVal, Context);
350351

351352
// Convert the value to the same width/sign as the condition.
352353
ConvertIntegerToTypeWarnOnOverflow(LoVal, CondWidth, CondIsSigned,
353354
CS->getLHS()->getLocStart(),
354355
diag::warn_case_value_overflow);
355356

357+
// If the LHS is not the same type as the condition, insert an implicit
358+
// cast.
359+
ImpCastExprToType(Lo, CondType);
360+
CS->setLHS(Lo);
361+
356362
// If this is a case range, remember it in CaseRanges, otherwise CaseVals.
357363
if (CS->getRHS())
358364
CaseRanges.push_back(std::make_pair(LoVal, CS));
@@ -391,13 +397,19 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch,
391397
for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
392398
CaseStmt *CR = CaseRanges[i].second;
393399
llvm::APSInt HiVal(32);
394-
CR->getRHS()->isIntegerConstantExpr(HiVal, Context);
400+
Expr *Hi = CR->getRHS();
401+
Hi->isIntegerConstantExpr(HiVal, Context);
395402

396403
// Convert the value to the same width/sign as the condition.
397404
ConvertIntegerToTypeWarnOnOverflow(HiVal, CondWidth, CondIsSigned,
398405
CR->getRHS()->getLocStart(),
399406
diag::warn_case_value_overflow);
400407

408+
// If the LHS is not the same type as the condition, insert an implicit
409+
// cast.
410+
ImpCastExprToType(Hi, CondType);
411+
CR->setRHS(Hi);
412+
401413
// If the low value is bigger than the high value, the case is empty.
402414
if (CaseRanges[i].first > HiVal) {
403415
Diag(CR->getLHS()->getLocStart(), diag::warn_case_empty_range,

clang/test/CodeGen/statements.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: clang %s -emit-llvm
2+
3+
void foo(int x) {
4+
switch (x) {
5+
case 111111111111111111111111111111111111111:
6+
bar();
7+
}
8+
}
9+

0 commit comments

Comments
 (0)