Again revert r222044 to resolve darwin objc test fails.

llvm-svn: 222047
This commit is contained in:
Anton Korobeynikov 2014-11-14 21:54:46 +00:00
parent 4ac0c0c0fd
commit 50fc68f2d9
4 changed files with 26 additions and 96 deletions

View File

@ -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 bool
CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
const char *StartSpecifier, 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 // Special-case some of Darwin's platform-independence types by suggesting
// casts to primitive types that are known to be large enough. // 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()) { if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
QualType CastTy; // Use a 'while' to peel off layers of typedefs.
std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E); QualType TyTy = IntendedTy;
if (!CastTy.isNull()) { while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) {
IntendedTy = CastTy; StringRef Name = UserTy->getDecl()->getName();
ShouldNotPrintDirectly = true; 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); 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 // In this case, the specifier is wrong and should be changed to match
// the argument. // the argument.
EmitFormatDiagnostic( EmitFormatDiagnostic(
@ -3615,11 +3572,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// The expression has a type that should not be printed directly. // 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 // We extract the name from the typedef because we don't want to show
// the underlying type in the diagnostic. // the underlying type in the diagnostic.
StringRef Name; StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName();
if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(ExprTy))
Name = TypedefTy->getDecl()->getName();
else
Name = CastTyName;
EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast) EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)
<< Name << IntendedTy << IsEnum << Name << IntendedTy << IsEnum
<< E->getSourceRange(), << E->getSourceRange(),

View File

@ -5711,7 +5711,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
RHS.get()->getType()->isVectorType()) RHS.get()->getType()->isVectorType())
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false);
QualType ResTy = UsualArithmeticConversions(LHS, RHS); UsualArithmeticConversions(LHS, RHS);
if (LHS.isInvalid() || RHS.isInvalid()) if (LHS.isInvalid() || RHS.isInvalid())
return QualType(); return QualType();
@ -5728,12 +5728,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// If both operands have arithmetic type, do the usual arithmetic conversions // If both operands have arithmetic type, do the usual arithmetic conversions
// to find a common type: C99 6.5.15p3,5. // to find a common type: C99 6.5.15p3,5.
if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType())
LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); return LHS.get()->getType();
RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
return ResTy;
}
// If both operands are the same structure or union type, the result is that // If both operands are the same structure or union type, the result is that
// type. // type.

View File

@ -4561,14 +4561,10 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// the usual arithmetic conversions are performed to bring them to a // the usual arithmetic conversions are performed to bring them to a
// common type, and the result is of that type. // common type, and the result is of that type.
if (LTy->isArithmeticType() && RTy->isArithmeticType()) { if (LTy->isArithmeticType() && RTy->isArithmeticType()) {
QualType ResTy = UsualArithmeticConversions(LHS, RHS); UsualArithmeticConversions(LHS, RHS);
if (LHS.isInvalid() || RHS.isInvalid()) if (LHS.isInvalid() || RHS.isInvalid())
return QualType(); return QualType();
return LHS.get()->getType();
LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
return ResTy;
} }
// -- The second and third operands have pointer type, or one has pointer // -- The second and third operands have pointer type, or one has pointer

View File

@ -98,19 +98,3 @@ void t8() {
const _Complex double test9const = 0; const _Complex double test9const = 0;
_Complex double test9func() { return test9const; } _Complex double test9func() { return test9const; }
// D6217
void t91() {
// Check for proper type promotion of conditional expression
char c[(int)(sizeof(typeof((0 ? 2.0f : (_Complex double) 2.0f))) - sizeof(_Complex double))];
// Check for proper codegen
(0 ? 2.0f : (_Complex double) 2.0f);
}
void t92() {
// Check for proper type promotion of conditional expression
char c[(int)(sizeof(typeof((0 ? (_Complex double) 2.0f : 2.0f))) - sizeof(_Complex double))];
// Check for proper codegen
(0 ? (_Complex double) 2.0f : 2.0f);
}