From: Kaelyn Takata Date: Tue, 27 Jan 2015 18:26:18 +0000 (+0000) Subject: Properly handle typos in the conditional of ?: expressions in C. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26fa5675bf3abe1f3c9371cb104c936c4f60ac27;p=clang Properly handle typos in the conditional of ?: expressions in C. In particular, remove the OpaqueExpr transformation from r225389 and move the correction of the conditional from CheckConditionalOperands to ActOnConditionalOp before the OpaqueExpr is created. This fixes the typo correction behavior in C code that uses the GNU extension for a binary ?: (without an expression between the "?" and the ":"). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@227220 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8b9950847f..2b507141e9 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5785,15 +5785,6 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprObjectKind &OK, SourceLocation QuestionLoc) { - if (!getLangOpts().CPlusPlus) { - // C cannot handle TypoExpr nodes on either side of a binop because it - // doesn't handle dependent types properly, so make sure any TypoExprs have - // been dealt with before checking the operands. - ExprResult CondResult = CorrectDelayedTyposInExpr(Cond); - if (!CondResult.isUsable()) return QualType(); - Cond = CondResult; - } - ExprResult LHSResult = CheckPlaceholderExpr(LHS.get()); if (!LHSResult.isUsable()) return QualType(); LHS = LHSResult; @@ -6175,6 +6166,15 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr) { + if (!getLangOpts().CPlusPlus) { + // C cannot handle TypoExpr nodes in the condition because it + // doesn't handle dependent types properly, so make sure any TypoExprs have + // been dealt with before checking the operands. + ExprResult CondResult = CorrectDelayedTyposInExpr(CondExpr); + if (!CondResult.isUsable()) return ExprError(); + CondExpr = CondResult.get(); + } + // If this is the gnu "x ?: y" extension, analyze the types as though the LHS // was the condition. OpaqueValueExpr *opaqueValue = nullptr; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 4de25c63b7..bf4ab267a4 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -6146,12 +6146,6 @@ public: ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); } - ExprResult TransformOpaqueValueExpr(OpaqueValueExpr *E) { - if (Expr *SE = E->getSourceExpr()) - return TransformExpr(SE); - return BaseTransform::TransformOpaqueValueExpr(E); - } - ExprResult Transform(Expr *E) { ExprResult Res; while (true) { diff --git a/test/Sema/typo-correction.c b/test/Sema/typo-correction.c index df7da797f0..8276737e4f 100644 --- a/test/Sema/typo-correction.c +++ b/test/Sema/typo-correction.c @@ -13,6 +13,11 @@ void PR21656() { a = b ? : 0; // expected-warning {{type specifier missing, defaults to 'int'}} \ // expected-error {{use of undeclared identifier 'b'}} +int foobar; // expected-note {{'foobar' declared here}} +a = goobar ?: 4; // expected-warning {{type specifier missing, defaults to 'int'}} \ + // expected-error {{use of undeclared identifier 'goobar'; did you mean 'foobar'?}} \ + // expected-error {{initializer element is not a compile-time constant}} + struct ContainerStuct { enum { SOME_ENUM }; // expected-note {{'SOME_ENUM' declared here}} };