From: Eli Friedman Date: Sat, 25 Apr 2009 23:46:54 +0000 (+0000) Subject: Fix for PR4074: allow subscripting non-lvalue arrays in C90 mode. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c32f8e9be486f8f8ec2e75eba36903f7cb1b73a;p=clang Fix for PR4074: allow subscripting non-lvalue arrays in C90 mode. I wasn't originally going to use this approach, but cases like test/Sema/expr-comma.c make things difficult. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70096 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 19f3157710..61d8e3b254 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -945,6 +945,8 @@ def err_arithmetic_nonfragile_interface : Error< "non-fragile ABI">; +def ext_subscript_non_lvalue : Extension< + "ISO C90 does not allow subscripting non-lvalue array">; def err_typecheck_subscript_value : Error< "subscripted value is not an array, pointer, or vector">; def err_typecheck_subscript_not_integer : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 873dd53f12..e789e54289 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1621,13 +1621,11 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, } else if (const PointerType *PTy = LHSTy->getAsPointerType()) { BaseExpr = LHSExp; IndexExpr = RHSExp; - // FIXME: need to deal with const... ResultType = PTy->getPointeeType(); } else if (const PointerType *PTy = RHSTy->getAsPointerType()) { // Handle the uncommon case of "123[Ptr]". BaseExpr = RHSExp; IndexExpr = LHSExp; - // FIXME: need to deal with const... ResultType = PTy->getPointeeType(); } else if (const VectorType *VTy = LHSTy->getAsVectorType()) { BaseExpr = LHSExp; // vectors: V[123] @@ -1635,6 +1633,30 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, // FIXME: need to deal with const... ResultType = VTy->getElementType(); + } else if (LHSTy->isArrayType()) { + // If we see an array that wasn't promoted by + // DefaultFunctionArrayConversion, it must be an array that + // wasn't promoted because of the C90 rule that doesn't + // allow promoting non-lvalue arrays. Warn, then + // force the promotion here. + Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << + LHSExp->getSourceRange(); + ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy)); + LHSTy = LHSExp->getType(); + + BaseExpr = LHSExp; + IndexExpr = RHSExp; + ResultType = LHSTy->getAsPointerType()->getPointeeType(); + } else if (RHSTy->isArrayType()) { + // Same as previous, except for 123[f().a] case + Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << + RHSExp->getSourceRange(); + ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy)); + RHSTy = RHSExp->getType(); + + BaseExpr = RHSExp; + IndexExpr = LHSExp; + ResultType = RHSTy->getAsPointerType()->getPointeeType(); } else { return ExprError(Diag(LLoc, diag::err_typecheck_subscript_value) << LHSExp->getSourceRange() << RHSExp->getSourceRange()); diff --git a/test/Sema/c89.c b/test/Sema/c89.c index 138d6fa249..3b1c7766fe 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -67,3 +67,14 @@ void test11 (int x[static 4]); /* expected-warning {{use of C99-specific array f void test12 (int x[const 4]) { /* expected-warning {{use of C99-specific array features}} */ int Y[x[1]]; /* expected-warning {{variable length arrays are a C99 feature, accepted as an extension}} */ } + +/* PR4074 */ +struct test13 { + int X[23]; +} test13a(); + +void test13b() { + int a = test13a().X[1]; /* expected-warning {{ISO C90 does not allow subscripting non-lvalue array}} */ + int b = 1[test13a().X]; /* expected-warning {{ISO C90 does not allow subscripting non-lvalue array}} */ +} +