]> granicus.if.org Git - clang/commitdiff
[Fixed Point Arithmetic] Fix for bug where integer literals could be treated as fixed...
authorLeonard Chan <leonardchan@google.com>
Tue, 17 Jul 2018 14:58:49 +0000 (14:58 +0000)
committerLeonard Chan <leonardchan@google.com>
Tue, 17 Jul 2018 14:58:49 +0000 (14:58 +0000)
This addresses a bug brought up in https://bugs.llvm.org/show_bug.cgi?id=38161 where integer literals could be treated as fixed point types and throw errors related to fixed point types when the 'k' or 'r' suffix used. The fix also addresses the second issue brought up with the assertion by not treating integers as fixed point types in the first place.

Integers that have suffixes 'k' and 'r' now throw the error `invalid suffix 'k/r' on integer constant`.

A few more tests were also added to ensure that fixed point types, and any errors/warnings related to them, are limited to C for now.

Prior discussion also at https://reviews.llvm.org/D46915.

Differential Revision: https://reviews.llvm.org/D49327

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337289 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/LiteralSupport.cpp
test/Frontend/fixed_point_errors.c
test/Frontend/fixed_point_errors.cpp
test/Frontend/fixed_point_not_enabled.c

index c1be3b2a97e5a64c13869098961dc0a835b1c60d..e695b2ba376547b346c25966a11892d45708b900 100644 (file)
@@ -572,10 +572,12 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
   checkSeparator(TokLoc, s, CSK_AfterDigits);
 
   // Initial scan to lookahead for fixed point suffix.
-  for (const char *c = s; c != ThisTokEnd; ++c) {
-    if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') {
-      saw_fixed_point_suffix = true;
-      break;
+  if (PP.getLangOpts().FixedPoint) {
+    for (const char *c = s; c != ThisTokEnd; ++c) {
+      if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') {
+        saw_fixed_point_suffix = true;
+        break;
+      }
     }
   }
 
@@ -589,12 +591,16 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
     switch (*s) {
     case 'R':
     case 'r':
+      if (!PP.getLangOpts().FixedPoint) break;
       if (isFract || isAccum) break;
+      if (!(saw_period || saw_exponent)) break;
       isFract = true;
       continue;
     case 'K':
     case 'k':
+      if (!PP.getLangOpts().FixedPoint) break;
       if (isFract || isAccum) break;
+      if (!(saw_period || saw_exponent)) break;
       isAccum = true;
       continue;
     case 'h':      // FP Suffix for "half".
@@ -734,7 +740,6 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
 
   if (!hadError && saw_fixed_point_suffix) {
     assert(isFract || isAccum);
-    //assert(radix == 16 || radix == 10);
   }
 }
 
index f55fc82f917f1972affa9cbded74df344c37fdfb..41427e343154efdec1b44adbc46a0f734bdcbf67 100644 (file)
@@ -148,3 +148,87 @@ _Accum dec_with_hex_exp1 = 0.1p10k;    // expected-error{{invalid suffix 'p10k'
 _Accum dec_with_hex_exp2 = 0.1P10k;    // expected-error{{invalid suffix 'P10k' on integer constant}}
 _Accum hex_with_dex_exp1 = 0x0.1e10k;  // expected-error{{hexadecimal floating constant requires an exponent}}
 _Accum hex_with_dex_exp2 = 0x0.1E10k;  // expected-error{{hexadecimal floating constant requires an exponent}}
+
+void CheckSuffixOnIntegerLiterals() {
+  _Accum short_acc_int;
+  _Accum acc_int;
+  _Accum long_acc_int;
+
+  _Accum u_short_acc_int;
+  _Accum u_acc_int;
+  _Accum u_long_acc_int;
+
+  _Fract short_fract_int;
+  _Fract fract_int;
+  _Fract long_fract_int;
+
+  _Fract u_short_fract_int;
+  _Fract u_fract_int;
+  _Fract u_long_fract_int;
+
+  // Decimal integer literals (non-zero)
+  short_acc_int = 10hk; // expected-error{{invalid suffix 'hk' on integer constant}}
+  acc_int = 10k;        // expected-error{{invalid suffix 'k' on integer constant}}
+  long_acc_int = 10lk;  // expected-error{{invalid suffix 'lk' on integer constant}}
+
+  u_short_acc_int = 10uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
+  u_acc_int = 10uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
+  u_long_acc_int = 10ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}
+
+  short_fract_int = 10hr; // expected-error{{invalid suffix 'hr' on integer constant}}
+  fract_int = 10r;        // expected-error{{invalid suffix 'r' on integer constant}}
+  long_fract_int = 10lr;  // expected-error{{invalid suffix 'lr' on integer constant}}
+
+  u_short_fract_int = 10uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
+  u_fract_int = 10ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
+  u_long_fract_int = 10ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}
+
+  // Decimal integer literals (0)
+  short_acc_int = 0hk; // expected-error{{invalid suffix 'hk' on integer constant}}
+  acc_int = 0k;        // expected-error{{invalid suffix 'k' on integer constant}}
+  long_acc_int = 0lk;  // expected-error{{invalid suffix 'lk' on integer constant}}
+
+  // Decimal integer literals (large number)
+  acc_int = 999999999999999999k;   // expected-error{{invalid suffix 'k' on integer constant}}
+  fract_int = 999999999999999999r; // expected-error{{invalid suffix 'r' on integer constant}}
+
+  // Octal integer literals
+  short_acc_int = 010hk; // expected-error{{invalid suffix 'hk' on integer constant}}
+  acc_int = 010k;        // expected-error{{invalid suffix 'k' on integer constant}}
+  long_acc_int = 010lk;  // expected-error{{invalid suffix 'lk' on integer constant}}
+
+  u_short_acc_int = 010uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
+  u_acc_int = 010uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
+  u_long_acc_int = 010ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}
+
+  short_fract_int = 010hr; // expected-error{{invalid suffix 'hr' on integer constant}}
+  fract_int = 010r;        // expected-error{{invalid suffix 'r' on integer constant}}
+  long_fract_int = 010lr;  // expected-error{{invalid suffix 'lr' on integer constant}}
+
+  u_short_fract_int = 010uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
+  u_fract_int = 010ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
+  u_long_fract_int = 010ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}
+
+  // Hexadecimal integer literals
+  short_acc_int = 0x10hk; // expected-error{{invalid suffix 'hk' on integer constant}}
+  acc_int = 0x10k;        // expected-error{{invalid suffix 'k' on integer constant}}
+  long_acc_int = 0x10lk;  // expected-error{{invalid suffix 'lk' on integer constant}}
+
+  u_short_acc_int = 0x10uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
+  u_acc_int = 0x10uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
+  u_long_acc_int = 0x10ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}
+
+  short_fract_int = 0x10hr; // expected-error{{invalid suffix 'hr' on integer constant}}
+  fract_int = 0x10r;        // expected-error{{invalid suffix 'r' on integer constant}}
+  long_fract_int = 0x10lr;  // expected-error{{invalid suffix 'lr' on integer constant}}
+
+  u_short_fract_int = 0x10uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
+  u_fract_int = 0x10ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
+  u_long_fract_int = 0x10ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}
+
+  // Using auto
+  auto auto_fract = 0r;  // expected-error{{invalid suffix 'r' on integer constant}}
+                         // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+  auto auto_accum = 0k;  // expected-error{{invalid suffix 'k' on integer constant}}
+                         // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+}
index 37027b4ef05d3b6e91b3c6f82be63ed486d6b38c..cdd90ceb7548f94a1eb0b3fcfeda37144a114999 100644 (file)
@@ -7,3 +7,8 @@ _Accum accum;                           // expected-error{{unknown type name '_A
 _Fract fract;                           // expected-error{{unknown type name '_Fract'}}
 _Sat _Accum sat_accum;                  // expected-error{{unknown type name '_Sat'}}
                                         // expected-error@-1{{expected ';' after top level declarator}}
+
+int accum_int = 10k;     // expected-error{{invalid suffix 'k' on integer constant}}
+int fract_int = 10r;     // expected-error{{invalid suffix 'r' on integer constant}}
+float accum_flt = 10.0k; // expected-error{{invalid suffix 'k' on floating constant}}
+float fract_flt = 10.0r; // expected-error{{invalid suffix 'r' on floating constant}}
index e5c82f54b62f0b672b87d19da4b9614cb51f429b..e7522213f98d61ced145c67f4c51505df8b1fa43 100644 (file)
@@ -13,3 +13,9 @@ short _Accum short_accum;             // expected-error{{compile with '-ffixed-p
 _Accum accum;                         // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
                                       // expected-warning@-1{{type specifier missing, defaults to 'int'}}
 long _Accum long_accum;               // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+
+// Cannot use fixed point suffixes
+int accum_int = 10k;     // expected-error{{invalid suffix 'k' on integer constant}}
+int fract_int = 10r;     // expected-error{{invalid suffix 'r' on integer constant}}
+float accum_flt = 10.0k; // expected-error{{invalid suffix 'k' on floating constant}}
+float fract_flt = 10.0r; // expected-error{{invalid suffix 'r' on floating constant}}