summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2014-11-14 21:54:46 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2014-11-14 21:54:46 +0000
commit50fc68f2d900776c8c764c51342b651a224a4c78 (patch)
tree469b398d097f966d9b18b9d07b45972a6fb95ad7 /clang/lib/Sema/SemaChecking.cpp
parent4ac0c0c0fd6ea07503346c05cb2615d680df7f06 (diff)
downloadbcm5719-llvm-50fc68f2d900776c8c764c51342b651a224a4c78.tar.gz
bcm5719-llvm-50fc68f2d900776c8c764c51342b651a224a4c78.zip
Again revert r222044 to resolve darwin objc test fails.
llvm-svn: 222047
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp88
1 files changed, 21 insertions, 67 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b27ce7c7098..31b643f1385 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3392,61 +3392,6 @@ static bool requiresParensToAddCast(const Expr *E) {
}
}
-static std::pair<QualType, StringRef>
-shouldNotPrintDirectly(const ASTContext &Context,
- QualType IntendedTy,
- const Expr *E) {
- // Use a 'while' to peel off layers of typedefs.
- QualType TyTy = IntendedTy;
- while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) {
- StringRef Name = UserTy->getDecl()->getName();
- QualType CastTy = llvm::StringSwitch<QualType>(Name)
- .Case("NSInteger", Context.LongTy)
- .Case("NSUInteger", Context.UnsignedLongTy)
- .Case("SInt32", Context.IntTy)
- .Case("UInt32", Context.UnsignedIntTy)
- .Default(QualType());
-
- if (!CastTy.isNull())
- return std::make_pair(CastTy, Name);
-
- TyTy = UserTy->desugar();
- }
-
- // Strip parens if necessary.
- if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
- return shouldNotPrintDirectly(Context,
- PE->getSubExpr()->getType(),
- PE->getSubExpr());
-
- // If this is a conditional expression, then its result type is constructed
- // via usual arithmetic conversions and thus there might be no necessary
- // typedef sugar there. Recurse to operands to check for NSInteger &
- // Co. usage condition.
- if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
- QualType TrueTy, FalseTy;
- StringRef TrueName, FalseName;
-
- std::tie(TrueTy, TrueName) =
- shouldNotPrintDirectly(Context,
- CO->getTrueExpr()->getType(),
- CO->getTrueExpr());
- std::tie(FalseTy, FalseName) =
- shouldNotPrintDirectly(Context,
- CO->getFalseExpr()->getType(),
- CO->getFalseExpr());
-
- if (TrueTy == FalseTy)
- return std::make_pair(TrueTy, TrueName);
- else if (TrueTy.isNull())
- return std::make_pair(FalseTy, FalseName);
- else if (FalseTy.isNull())
- return std::make_pair(TrueTy, TrueName);
- }
-
- return std::make_pair(QualType(), StringRef());
-}
-
bool
CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
const char *StartSpecifier,
@@ -3538,13 +3483,25 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// Special-case some of Darwin's platform-independence types by suggesting
// casts to primitive types that are known to be large enough.
- bool ShouldNotPrintDirectly = false; StringRef CastTyName;
+ bool ShouldNotPrintDirectly = false;
if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
- QualType CastTy;
- std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E);
- if (!CastTy.isNull()) {
- IntendedTy = CastTy;
- ShouldNotPrintDirectly = true;
+ // Use a 'while' to peel off layers of typedefs.
+ QualType TyTy = IntendedTy;
+ while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) {
+ StringRef Name = UserTy->getDecl()->getName();
+ QualType CastTy = llvm::StringSwitch<QualType>(Name)
+ .Case("NSInteger", S.Context.LongTy)
+ .Case("NSUInteger", S.Context.UnsignedLongTy)
+ .Case("SInt32", S.Context.IntTy)
+ .Case("UInt32", S.Context.UnsignedIntTy)
+ .Default(QualType());
+
+ if (!CastTy.isNull()) {
+ ShouldNotPrintDirectly = true;
+ IntendedTy = CastTy;
+ break;
+ }
+ TyTy = UserTy->desugar();
}
}
@@ -3561,7 +3518,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
- if (IntendedTy == ExprTy && !ShouldNotPrintDirectly) {
+ if (IntendedTy == ExprTy) {
// In this case, the specifier is wrong and should be changed to match
// the argument.
EmitFormatDiagnostic(
@@ -3615,11 +3572,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// The expression has a type that should not be printed directly.
// We extract the name from the typedef because we don't want to show
// the underlying type in the diagnostic.
- StringRef Name;
- if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(ExprTy))
- Name = TypedefTy->getDecl()->getName();
- else
- Name = CastTyName;
+ StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName();
+
EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)
<< Name << IntendedTy << IsEnum
<< E->getSourceRange(),
OpenPOWER on IntegriCloud