Treat unary + as an actual operator, not a no-op.
This is necessary both to detect errors (using unary + on non-arithmetic types) and to correctly perform the integer promotions when unary + is used (which can be detected with sizeof or _Generic).
This commit is contained in:
parent
f027286b6a
commit
e71fe5d785
|
@ -202,7 +202,8 @@ type
|
||||||
otherch, {other non-whitespace char (pp-token)}
|
otherch, {other non-whitespace char (pp-token)}
|
||||||
eolsy,eofsy, {control characters}
|
eolsy,eofsy, {control characters}
|
||||||
typedef, {user types}
|
typedef, {user types}
|
||||||
uminus,uand,uasterisk, {converted operations}
|
{converted operations}
|
||||||
|
uminus,uplus,uand,uasterisk,
|
||||||
parameteroper,castoper,opplusplus,opminusminus,compoundliteral,
|
parameteroper,castoper,opplusplus,opminusminus,compoundliteral,
|
||||||
macroParm); {macro language}
|
macroParm); {macro language}
|
||||||
|
|
||||||
|
|
|
@ -1659,6 +1659,7 @@ var
|
||||||
tildech, {~}
|
tildech, {~}
|
||||||
excch, {!}
|
excch, {!}
|
||||||
uminus, {unary -}
|
uminus, {unary -}
|
||||||
|
uplus, {unary +}
|
||||||
uand, {unary &}
|
uand, {unary &}
|
||||||
uasterisk: begin {unary *}
|
uasterisk: begin {unary *}
|
||||||
op^.left := Pop;
|
op^.left := Pop;
|
||||||
|
@ -1810,6 +1811,7 @@ var
|
||||||
ekind := intconst;
|
ekind := intconst;
|
||||||
end;
|
end;
|
||||||
uminus : op1 := -op1; {unary -}
|
uminus : op1 := -op1; {unary -}
|
||||||
|
uplus : ; {unary +}
|
||||||
uasterisk : Error(79); {unary *}
|
uasterisk : Error(79); {unary *}
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
|
@ -1852,6 +1854,7 @@ var
|
||||||
if llop1.lo = 0 then
|
if llop1.lo = 0 then
|
||||||
llop1.hi := llop1.hi + 1;
|
llop1.hi := llop1.hi + 1;
|
||||||
end;
|
end;
|
||||||
|
uplus : ; {unary +}
|
||||||
uasterisk : Error(79); {unary *}
|
uasterisk : Error(79); {unary *}
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
|
@ -1880,6 +1883,11 @@ var
|
||||||
op^.token.kind := ekind;
|
op^.token.kind := ekind;
|
||||||
op^.token.rval := -rop1;
|
op^.token.rval := -rop1;
|
||||||
end;
|
end;
|
||||||
|
uplus : begin {unary +}
|
||||||
|
op^.token.class := realConstant;
|
||||||
|
op^.token.kind := ekind;
|
||||||
|
op^.token.rval := rop1;
|
||||||
|
end;
|
||||||
excch : begin {!}
|
excch : begin {!}
|
||||||
op^.token.class := intConstant;
|
op^.token.class := intConstant;
|
||||||
op^.token.kind := intconst;
|
op^.token.kind := intconst;
|
||||||
|
@ -2278,10 +2286,7 @@ if token.kind in startExpression then begin
|
||||||
asteriskch: token.kind := uasterisk;
|
asteriskch: token.kind := uasterisk;
|
||||||
minusch : token.kind := uminus;
|
minusch : token.kind := uminus;
|
||||||
andch : token.kind := uand;
|
andch : token.kind := uand;
|
||||||
plusch : begin
|
plusch : token.kind := uplus;
|
||||||
NextToken;
|
|
||||||
goto 2;
|
|
||||||
end;
|
|
||||||
otherwise : Error(57);
|
otherwise : Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
if icp[token.kind] = notAnOperation then
|
if icp[token.kind] = notAnOperation then
|
||||||
|
@ -2305,7 +2310,7 @@ if token.kind in startExpression then begin
|
||||||
end; {if}
|
end; {if}
|
||||||
if token.kind in {make sure we get what we want}
|
if token.kind in {make sure we get what we want}
|
||||||
[plusplusop,minusminusop,sizeofsy,_Alignofsy,tildech,excch,
|
[plusplusop,minusminusop,sizeofsy,_Alignofsy,tildech,excch,
|
||||||
uasterisk,uminus,uand] then begin
|
uasterisk,uminus,uplus,uand] then begin
|
||||||
if not expectingTerm then begin
|
if not expectingTerm then begin
|
||||||
Error(38);
|
Error(38);
|
||||||
Skip;
|
Skip;
|
||||||
|
@ -4485,6 +4490,19 @@ case tree^.token.kind of
|
||||||
end; {case}
|
end; {case}
|
||||||
end; {case uminus}
|
end; {case uminus}
|
||||||
|
|
||||||
|
uplus: begin {unary +}
|
||||||
|
GenerateCode(tree^.left);
|
||||||
|
if expressionType^.kind <> scalarType then
|
||||||
|
error(66)
|
||||||
|
else case UsualUnaryConversions of
|
||||||
|
cgByte,cgUByte,cgWord,cgUWord,cgLong,cgULong,cgQuad,cgUQuad,
|
||||||
|
cgReal,cgDouble,cgComp,cgExtended:
|
||||||
|
;
|
||||||
|
otherwise:
|
||||||
|
error(66);
|
||||||
|
end; {case}
|
||||||
|
end; {case uplus}
|
||||||
|
|
||||||
tildech: begin {~}
|
tildech: begin {~}
|
||||||
GenerateCode(tree^.left);
|
GenerateCode(tree^.left);
|
||||||
if expressionType^.kind <> scalarType then
|
if expressionType^.kind <> scalarType then
|
||||||
|
|
|
@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
|
||||||
{$segment 'HEADER'}
|
{$segment 'HEADER'}
|
||||||
|
|
||||||
const
|
const
|
||||||
symFileVersion = 35; {version number of .sym file format}
|
symFileVersion = 36; {version number of .sym file format}
|
||||||
|
|
||||||
var
|
var
|
||||||
inhibitHeader: boolean; {should .sym includes be blocked?}
|
inhibitHeader: boolean; {should .sym includes be blocked?}
|
||||||
|
|
|
@ -1060,7 +1060,9 @@ case token.kind of
|
||||||
|
|
||||||
uminus: write('-');
|
uminus: write('-');
|
||||||
|
|
||||||
uand: write('+');
|
uplus: write('+');
|
||||||
|
|
||||||
|
uand: write('&');
|
||||||
|
|
||||||
uasterisk: write('*');
|
uasterisk: write('*');
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,8 @@ charSym start single character symbols
|
||||||
enum (bareqop,poundpoundop,dotdotdotsy)
|
enum (bareqop,poundpoundop,dotdotdotsy)
|
||||||
enum (eolsy,eofsy) control characters
|
enum (eolsy,eofsy) control characters
|
||||||
enum (typedef) user types
|
enum (typedef) user types
|
||||||
enum (uminus,uand,uasterisk) converted operations
|
! converted operations
|
||||||
|
enum (uminus,uplus,uand,uasterisk)
|
||||||
enum (parameteroper,castoper,opplusplus,opminusminus,compoundliteral)
|
enum (parameteroper,castoper,opplusplus,opminusminus,compoundliteral)
|
||||||
enum (macroParm) macro language
|
enum (macroParm) macro language
|
||||||
|
|
||||||
|
@ -470,6 +471,7 @@ icp start in-coming priority for expression
|
||||||
dc i1'200' eofsy
|
dc i1'200' eofsy
|
||||||
dc i1'200' typedef
|
dc i1'200' typedef
|
||||||
dc i1'16' uminus
|
dc i1'16' uminus
|
||||||
|
dc i1'16' uplus
|
||||||
dc i1'16' uand
|
dc i1'16' uand
|
||||||
dc i1'16' uasterisk
|
dc i1'16' uasterisk
|
||||||
dc i1'200' parameteroper
|
dc i1'200' parameteroper
|
||||||
|
@ -647,6 +649,7 @@ isp start in stack priority for expression
|
||||||
dc i1'0' eofsy
|
dc i1'0' eofsy
|
||||||
dc i1'0' typedef
|
dc i1'0' typedef
|
||||||
dc i1'16' uminus
|
dc i1'16' uminus
|
||||||
|
dc i1'16' uplus
|
||||||
dc i1'16' uand
|
dc i1'16' uand
|
||||||
dc i1'16' uasterisk
|
dc i1'16' uasterisk
|
||||||
dc i1'0' parameteroper
|
dc i1'0' parameteroper
|
||||||
|
|
2
cc.notes
2
cc.notes
|
@ -2049,6 +2049,8 @@ int foo(int[42]);
|
||||||
|
|
||||||
225. According to the C99 and later standards, a line continuation with \ should let a // comment continue to the next line. ORCA/C now behaves accordingly.
|
225. According to the C99 and later standards, a line continuation with \ should let a // comment continue to the next line. ORCA/C now behaves accordingly.
|
||||||
|
|
||||||
|
226. The unary + operator should apply the integer promotions to its operand, e.g. promoting char to int. This can affect the value of sizeof(+expression).
|
||||||
|
|
||||||
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
||||||
|
|
||||||
1. In some situations, fread() reread the first 1K or so of the file.
|
1. In some situations, fread() reread the first 1K or so of the file.
|
||||||
|
|
Loading…
Reference in New Issue