[cfe-commits] r116029 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaStmt.cpp test/Sema/Inputs/conversion.h test/Sema/conversion.c
John McCall
rjmccall at apple.com
Thu Oct 7 19:01:29 PDT 2010
Author: rjmccall
Date: Thu Oct 7 21:01:28 2010
New Revision: 116029
URL: http://llvm.org/viewvc/llvm-project?rev=116029&view=rev
Log:
Track the location of the context requiring an implicit conversion and use it
to white-list conversions required by system headers. rdar://problem/8232669
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/Sema/Inputs/conversion.h
cfe/trunk/test/Sema/conversion.c
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct 7 21:01:28 2010
@@ -4472,7 +4472,7 @@
void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
SourceLocation ReturnLoc);
void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
- void CheckImplicitConversions(Expr *E);
+ void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
/// \brief The parser's current scope.
///
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Oct 7 21:01:28 2010
@@ -2434,7 +2434,7 @@
IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));
}
-void AnalyzeImplicitConversions(Sema &S, Expr *E);
+void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC);
static bool IsZero(Sema &S, Expr *E) {
// Suppress cases where we are comparing against an enum constant.
@@ -2487,8 +2487,8 @@
/// Analyze the operands of the given comparison. Implements the
/// fallback case from AnalyzeComparison.
void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) {
- AnalyzeImplicitConversions(S, E->getLHS());
- AnalyzeImplicitConversions(S, E->getRHS());
+ AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
+ AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
}
/// \brief Implements -Wsign-compare.
@@ -2533,8 +2533,8 @@
// Go ahead and analyze implicit conversions in the operands. Note
// that we skip the implicit conversions on both sides.
- AnalyzeImplicitConversions(S, lex);
- AnalyzeImplicitConversions(S, rex);
+ AnalyzeImplicitConversions(S, lex, E->getOperatorLoc());
+ AnalyzeImplicitConversions(S, rex, E->getOperatorLoc());
// If the signed range is non-negative, -Wsign-compare won't fire,
// but we should still check for comparisons which are always true
@@ -2564,12 +2564,14 @@
}
/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
-void DiagnoseImpCast(Sema &S, Expr *E, QualType T, unsigned diag) {
- S.Diag(E->getExprLoc(), diag) << E->getType() << T << E->getSourceRange();
+void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext,
+ unsigned diag) {
+ S.Diag(E->getExprLoc(), diag)
+ << E->getType() << T << E->getSourceRange() << SourceRange(CContext);
}
void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
- bool *ICContext = 0) {
+ SourceLocation CC, bool *ICContext = 0) {
if (E->isTypeDependent() || E->isValueDependent()) return;
const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
@@ -2577,6 +2579,13 @@
if (Source == Target) return;
if (Target->isDependentType()) return;
+ // If the conversion context location is invalid or instantiated
+ // from a system macro, don't complain.
+ if (CC.isInvalid() ||
+ (CC.isMacroID() && S.Context.getSourceManager().isInSystemHeader(
+ S.Context.getSourceManager().getSpellingLoc(CC))))
+ return;
+
// Never diagnose implicit casts to bool.
if (Target->isSpecificBuiltinType(BuiltinType::Bool))
return;
@@ -2584,7 +2593,7 @@
// Strip vector types.
if (isa<VectorType>(Source)) {
if (!isa<VectorType>(Target))
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_vector_scalar);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar);
Source = cast<VectorType>(Source)->getElementType().getTypePtr();
Target = cast<VectorType>(Target)->getElementType().getTypePtr();
@@ -2593,7 +2602,7 @@
// Strip complex types.
if (isa<ComplexType>(Source)) {
if (!isa<ComplexType>(Target))
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_complex_scalar);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_complex_scalar);
Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
Target = cast<ComplexType>(Target)->getElementType().getTypePtr();
@@ -2621,7 +2630,7 @@
return;
}
- DiagnoseImpCast(S, E, T, diag::warn_impcast_float_precision);
+ DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision);
}
return;
}
@@ -2629,7 +2638,7 @@
// If the target is integral, always warn.
if ((TargetBT && TargetBT->isInteger()))
// TODO: don't warn for integer values?
- DiagnoseImpCast(S, E, T, diag::warn_impcast_float_integer);
+ DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_integer);
return;
}
@@ -2644,8 +2653,8 @@
// People want to build with -Wshorten-64-to-32 and not -Wconversion
// and by god we'll let them.
if (SourceRange.Width == 64 && TargetRange.Width == 32)
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_64_32);
- return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_precision);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_64_32);
+ return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision);
}
if ((TargetRange.NonNegative && !SourceRange.NonNegative) ||
@@ -2663,7 +2672,7 @@
*ICContext = true;
}
- return DiagnoseImpCast(S, E, T, DiagID);
+ return DiagnoseImpCast(S, E, T, CC, DiagID);
}
return;
@@ -2672,24 +2681,26 @@
void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T);
void CheckConditionalOperand(Sema &S, Expr *E, QualType T,
- bool &ICContext) {
+ SourceLocation CC, bool &ICContext) {
E = E->IgnoreParenImpCasts();
if (isa<ConditionalOperator>(E))
return CheckConditionalOperator(S, cast<ConditionalOperator>(E), T);
- AnalyzeImplicitConversions(S, E);
+ AnalyzeImplicitConversions(S, E, CC);
if (E->getType() != T)
- return CheckImplicitConversion(S, E, T, &ICContext);
+ return CheckImplicitConversion(S, E, T, CC, &ICContext);
return;
}
void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) {
- AnalyzeImplicitConversions(S, E->getCond());
+ SourceLocation CC = E->getQuestionLoc();
+
+ AnalyzeImplicitConversions(S, E->getCond(), CC);
bool Suspicious = false;
- CheckConditionalOperand(S, E->getTrueExpr(), T, Suspicious);
- CheckConditionalOperand(S, E->getFalseExpr(), T, Suspicious);
+ CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious);
+ CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious);
// If -Wconversion would have warned about either of the candidates
// for a signedness conversion to the context type...
@@ -2708,10 +2719,10 @@
if (E->getType() != T) {
Suspicious = false;
CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(),
- E->getType(), &Suspicious);
+ E->getType(), CC, &Suspicious);
if (!Suspicious)
CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(),
- E->getType(), &Suspicious);
+ E->getType(), CC, &Suspicious);
if (!Suspicious)
return;
}
@@ -2727,7 +2738,7 @@
/// AnalyzeImplicitConversions - Find and report any interesting
/// implicit conversions in the given expression. There are a couple
/// of competing diagnostics here, -Wconversion and -Wsign-compare.
-void AnalyzeImplicitConversions(Sema &S, Expr *OrigE) {
+void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) {
QualType T = OrigE->getType();
Expr *E = OrigE->IgnoreParenImpCasts();
@@ -2743,14 +2754,14 @@
// The non-canonical typecheck is just an optimization;
// CheckImplicitConversion will filter out dead implicit conversions.
if (E->getType() != T)
- CheckImplicitConversion(S, E, T);
+ CheckImplicitConversion(S, E, T, CC);
// Now continue drilling into this expression.
// Skip past explicit casts.
if (isa<ExplicitCastExpr>(E)) {
E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts();
- return AnalyzeImplicitConversions(S, E);
+ return AnalyzeImplicitConversions(S, E, CC);
}
// Do a somewhat different check with comparison operators.
@@ -2767,9 +2778,10 @@
if (isa<SizeOfAlignOfExpr>(E)) return;
// Now just recurse over the expression's children.
+ CC = E->getExprLoc();
for (Stmt::child_iterator I = E->child_begin(), IE = E->child_end();
I != IE; ++I)
- AnalyzeImplicitConversions(S, cast<Expr>(*I));
+ AnalyzeImplicitConversions(S, cast<Expr>(*I), CC);
}
} // end anonymous namespace
@@ -2777,7 +2789,11 @@
/// Diagnoses "dangerous" implicit conversions within the given
/// expression (which is a full expression). Implements -Wconversion
/// and -Wsign-compare.
-void Sema::CheckImplicitConversions(Expr *E) {
+///
+/// \param CC the "context" location of the implicit conversion, i.e.
+/// the most location of the syntactic entity requiring the implicit
+/// conversion
+void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) {
// Don't diagnose in unevaluated contexts.
if (ExprEvalContexts.back().Context == Sema::Unevaluated)
return;
@@ -2786,7 +2802,8 @@
if (E->isTypeDependent() || E->isValueDependent())
return;
- AnalyzeImplicitConversions(*this, E);
+ // This is not the right CC for (e.g.) a variable initialization.
+ AnalyzeImplicitConversions(*this, E, CC);
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Oct 7 21:01:28 2010
@@ -4326,6 +4326,9 @@
Init->setType(DclT);
}
+ // Check any implicit conversions within the expression.
+ CheckImplicitConversions(Init, VDecl->getLocation());
+
Init = MaybeCreateCXXExprWithTemporaries(Init);
// Attach the initializer to the decl.
VDecl->setInit(Init);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Oct 7 21:01:28 2010
@@ -136,6 +136,7 @@
return true;
Arg = Result.takeAs<Expr>();
+ CheckImplicitConversions(Arg, EqualLoc);
Arg = MaybeCreateCXXExprWithTemporaries(Arg);
// Okay: add the default argument to the parameter
@@ -1276,6 +1277,8 @@
MultiExprArg(*this, Args, NumArgs), 0);
if (MemberInit.isInvalid())
return true;
+
+ CheckImplicitConversions(MemberInit.get(), LParenLoc);
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
@@ -1407,6 +1410,8 @@
MultiExprArg(*this, Args, NumArgs), 0);
if (BaseInit.isInvalid())
return true;
+
+ CheckImplicitConversions(BaseInit.get(), LParenLoc);
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
@@ -5356,6 +5361,7 @@
return true;
Expr *Temp = TempResult.takeAs<Expr>();
+ CheckImplicitConversions(Temp, VD->getLocation());
MarkDeclarationReferenced(VD->getLocation(), Constructor);
Temp = MaybeCreateCXXExprWithTemporaries(Temp);
VD->setInit(Temp);
@@ -5489,6 +5495,8 @@
VDecl->setInvalidDecl();
return;
}
+
+ CheckImplicitConversions(Result.get(), LParenLoc);
Result = MaybeCreateCXXExprWithTemporaries(Result.get());
VDecl->setInit(Result.takeAs<Expr>());
@@ -6834,7 +6842,7 @@
// is required (e.g., because it would call a trivial default constructor)
if (!MemberInit.get() || MemberInit.isInvalid())
continue;
-
+
Member =
new (Context) CXXBaseOrMemberInitializer(Context,
Field, SourceLocation(),
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Oct 7 21:01:28 2010
@@ -2962,9 +2962,6 @@
Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
assert(SubExpr && "sub expression can't be null!");
- // Check any implicit conversions within the expression.
- CheckImplicitConversions(SubExpr);
-
unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
assert(ExprTemporaries.size() >= FirstTemporary);
if (ExprTemporaries.size() == FirstTemporary)
@@ -3381,5 +3378,7 @@
ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
if (!FullExpr) return ExprError();
+
+ CheckImplicitConversions(FullExpr);
return MaybeCreateCXXExprWithTemporaries(FullExpr);
}
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Oct 7 21:01:28 2010
@@ -446,6 +446,7 @@
Cond = CondResult.take();
if (!CondVar) {
+ CheckImplicitConversions(Cond, SwitchLoc);
CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
if (CondResult.isInvalid())
return StmtError();
@@ -889,6 +890,7 @@
if (CheckBooleanCondition(Cond, DoLoc))
return StmtError();
+ CheckImplicitConversions(Cond, DoLoc);
ExprResult CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
if (CondResult.isInvalid())
return StmtError();
@@ -1173,8 +1175,10 @@
return StmtError();
}
- if (RetValExp)
+ if (RetValExp) {
+ CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
+ }
RetValExp = Res.takeAs<Expr>();
if (RetValExp)
@@ -1227,6 +1231,7 @@
<< RetValExp->getSourceRange();
}
+ CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
}
@@ -1269,8 +1274,10 @@
CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
}
- if (RetValExp)
+ if (RetValExp) {
+ CheckImplicitConversions(RetValExp, ReturnLoc);
RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp);
+ }
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
}
Modified: cfe/trunk/test/Sema/Inputs/conversion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/Inputs/conversion.h?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/test/Sema/Inputs/conversion.h (original)
+++ cfe/trunk/test/Sema/Inputs/conversion.h Thu Oct 7 21:01:28 2010
@@ -1,3 +1,4 @@
/* Fake system header for Sema/conversion.c */
#define LONG_MAX __LONG_MAX__
+#define SETBIT(set,bit) do { int i = bit; set[i/(8*sizeof(set[0]))] |= (1 << (i%(8*sizeof(set)))); } while(0)
Modified: cfe/trunk/test/Sema/conversion.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conversion.c?rev=116029&r1=116028&r2=116029&view=diff
==============================================================================
--- cfe/trunk/test/Sema/conversion.c (original)
+++ cfe/trunk/test/Sema/conversion.c Thu Oct 7 21:01:28 2010
@@ -297,3 +297,16 @@
unsigned u2 = -1; // expected-warning {{implicit conversion changes signedness}}
u2 = -1; // expected-warning {{implicit conversion changes signedness}}
}
+
+// <rdar://problem/8232669>: don't warn about conversions required by
+// contexts in system headers
+void test_8232669(void) {
+ unsigned bitset[20];
+ SETBIT(bitset, 0);
+
+ unsigned y = 50;
+ SETBIT(bitset, y);
+
+#define USER_SETBIT(set,bit) do { int i = bit; set[i/(8*sizeof(set[0]))] |= (1 << (i%(8*sizeof(set)))); } while(0)
+ USER_SETBIT(bitset, 0); // expected-warning 2 {{implicit conversion changes signedness}}
+}
More information about the cfe-commits
mailing list