mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 03:26:06 +00:00
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. llvm-svn: 70096
This commit is contained in:
parent
0dedefe4f2
commit
ab2784f2c1
@ -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<
|
||||
|
@ -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());
|
||||
|
@ -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}} */
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user