]> granicus.if.org Git - clang/commitdiff
Fix for PR4074: allow subscripting non-lvalue arrays in C90 mode.
authorEli Friedman <eli.friedman@gmail.com>
Sat, 25 Apr 2009 23:46:54 +0000 (23:46 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 25 Apr 2009 23:46:54 +0000 (23:46 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/Sema/c89.c

index 19f31577106875b7020e5abfe5b12efb95478c90..61d8e3b254a79dacea965057abc57e5085253740 100644 (file)
@@ -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<
index 873dd53f12c222ce7c0ac774e14804874aa6aea0..e789e54289350f7873dd39423d803130340b45de 100644 (file)
@@ -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());
index 138d6fa24965014c8e5eccd105027a839b7ace03..3b1c7766fe564fb8e8fae8c1e897994e5e287f01 100644 (file)
@@ -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}} */
+}
+