Save and restore type spec when evaluating expressions in a type name.

Failing to do this could allow the type spec to be overwritten if the expression contained another type name within it (e.g. a cast). This could cause the wrong type to be computed, which could lead to incorrect behavior for constructs that use type names, e.g. sizeof.

Here is an example program that demonstrated the problem:

int main(void) {
        return sizeof(short[(long)50]);
}
This commit is contained in:
Stephen Heumann 2022-01-12 21:53:23 -06:00
parent 3b35a65b1d
commit 3acf5844c2
2 changed files with 5 additions and 0 deletions

View File

@ -4069,6 +4069,7 @@ var
var
pcount: integer; {paren counter}
tp: typePtr; {work pointer}
ltypeSpec: typePtr; {copy of type specifier}
begin {NonEmptyAbstractDeclarator}
if token.kind = lparench then begin
@ -4138,7 +4139,9 @@ var
if token.kind = rbrackch then
expressionValue := 0
else begin
ltypeSpec := typeSpec;
Expression(arrayExpression, [rbrackch]);
typeSpec := ltypeSpec;
if expressionValue <= 0 then begin
Error(45);
expressionValue := 1;

View File

@ -1697,6 +1697,8 @@ int foo(int[42]);
172. When certain negative integers that are multiples of 65536 were converted from floating-point types to long, long long, or comp, an incorrect value might be produced due to a bug in SANE. ORCA/C now includes workarounds to avoid this bug in several situations, although it might still occur in certain other ones.
173. sizeof could give the wrong value if the type contained a nested use of a type name within an array length expression, e.g. sizeof(short[(long)50]).
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.