hokein created this revision.
Herald added subscribers: cfe-commits, dang, arphaman, kbarton, nemanjai.
Herald added a project: clang.
hokein requested review of this revision.
Herald added a subscriber: wuzish.

This is a large patch containing all required changes, want early
feedback.

what does this patch do?

- support dependent mechanisam (only for error-recovery) in C-only codepath;
- allows building RecoveryExpr for C;
- remove all early TypoCorrection technical debet in clang;

This will be split into different patches:

- build dependent binary operator for C: https://reviews.llvm.org/D84226
- build dependent callexpr in C for error-recovery: 
https://reviews.llvm.org/D84304
- suppress spurious "typecheck_cond_expect_scalar" diagnostic: 
https://reviews.llvm.org/D84322
- suppress spurious "err_typecheck_expect_scalar_operand" diagnostic : 
https://reviews.llvm.org/D84387
- adjust all existing tests when enabled recovery-expr for C: 
https://reviews.llvm.org/D84970

TESTED: ninja check-clang


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85025

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/Expr.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/AST/ast-dump-recovery.c
  clang/test/CodeGen/builtins-ppc-error.c
  clang/test/CodeGen/builtins-systemz-zvector-error.c
  clang/test/CodeGen/builtins-systemz-zvector2-error.c
  clang/test/CodeGen/builtins-systemz-zvector3-error.c
  clang/test/Index/complete-switch.c
  clang/test/OpenMP/begin_declare_variant_messages.c
  clang/test/OpenMP/declare_variant_messages.c
  clang/test/Parser/objc-foreach-syntax.m
  clang/test/Sema/__try.c
  clang/test/Sema/enum.c
  clang/test/Sema/error-dependence.c
  clang/test/Sema/typo-correction.c

Index: clang/test/Sema/typo-correction.c
===================================================================
--- clang/test/Sema/typo-correction.c
+++ clang/test/Sema/typo-correction.c
@@ -14,7 +14,7 @@
               // expected-error {{use of undeclared identifier 'b'}}
 
 int foobar;  // expected-note {{'foobar' declared here}}
-a = goobar ?: 4;  // expected-warning {{type specifier missing, defaults to 'int'}} \
+new_a = goobar ?: 4;  // expected-warning {{type specifier missing, defaults to 'int'}} \
                   // expected-error {{use of undeclared identifier 'goobar'; did you mean 'foobar'?}} \
                   // expected-error {{initializer element is not a compile-time constant}}
 
@@ -50,10 +50,10 @@
   cabs(errij);  // expected-error {{use of undeclared identifier 'errij'}}
 }
 
-extern long afunction(int); // expected-note {{'afunction' declared here}}
+extern long afunction(int);
 void fn2() {
   f(THIS_IS_AN_ERROR, // expected-error {{use of undeclared identifier 'THIS_IS_AN_ERROR'}}
-    afunction(afunction_));  // expected-error {{use of undeclared identifier 'afunction_'; did you mean 'afunction'?}}
+    afunction(afunction_));  // expected-error {{use of undeclared identifier 'afunction_'}}
 }
 
 int d = X ? d : L; // expected-error 2 {{use of undeclared identifier}}
Index: clang/test/Sema/error-dependence.c
===================================================================
--- /dev/null
+++ clang/test/Sema/error-dependence.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -frecovery-ast -fno-recovery-ast-type -fc-dependence %s
+
+int call(int); // expected-note 2{{'call' declared here}}
+
+void test1(int s) {
+  // verify "assigning to 'int' from incompatible type '<dependent type>'" is
+  // not emitted.
+  s = call(); // expected-error {{too few arguments to function call}}
+
+  // verify disgnostic "called object type '<dependent type>' is not a function
+  // or function pointer" is not emitted.
+  (*__builtin_classify_type)(1); // expected-error {{builtin functions must be directly called}}
+}
+
+void test2(int *ptr, float f) {
+  // verify diagnostic "used type '<dependent type>' where arithmetic or pointer
+  // type is required" is not emitted.
+  ptr > f ? ptr : f; // expected-error {{invalid operands to binary expression}}
+}
+
+void test3(float f) {
+  // verify diagnostic "operand of type '<dependent type>' where arithmetic or
+  // pointer type is required" is not emitted.
+  f = (float)call(); // expected-error {{too few arguments to function call}}
+}
Index: clang/test/Sema/enum.c
===================================================================
--- clang/test/Sema/enum.c
+++ clang/test/Sema/enum.c
@@ -100,7 +100,8 @@
 // PR7911
 extern enum PR7911T PR7911V; // expected-warning{{ISO C forbids forward references to 'enum' types}}
 void PR7911F() {
-  switch (PR7911V); // expected-error {{statement requires expression of integer type}}
+  switch (PR7911V); // expected-error {{statement requires expression of integer type}} \
+                    // expected-warning {{switch statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
 }
 
 char test5[__has_feature(enumerator_attributes) ? 1 : -1];
Index: clang/test/Sema/__try.c
===================================================================
--- clang/test/Sema/__try.c
+++ clang/test/Sema/__try.c
@@ -51,8 +51,8 @@
 
 void TEST() {
   __except ( FilterExpression() ) { // expected-warning{{implicit declaration of function '__except' is invalid in C99}} \
-    // expected-error{{too few arguments to function call, expected 1, have 0}}
-
+    // expected-error{{too few arguments to function call, expected 1, have 0}} \
+    // expected-error{{expected ';' after expression}}
   }
 }
 
Index: clang/test/Parser/objc-foreach-syntax.m
===================================================================
--- clang/test/Parser/objc-foreach-syntax.m
+++ clang/test/Parser/objc-foreach-syntax.m
@@ -21,5 +21,8 @@
 
 
 static int test7(id keys) {
-  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}}
+  // FIXME: would be nice to suppress the secondary diagnostics.
+  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}} \
+                           // expected-error {{expected ';' in 'for' statement specifier}} \
+                           // expected-warning {{expression result unused}}
 }
Index: clang/test/OpenMP/declare_variant_messages.c
===================================================================
--- clang/test/OpenMP/declare_variant_messages.c
+++ clang/test/OpenMP/declare_variant_messages.c
@@ -10,7 +10,7 @@
 #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
 #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo // expected-error {{expected ')'}} expected-error {{expected 'match' clause on 'omp declare variant' directive}} expected-note {{to match this '('}}
-#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}}
+#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} expected-error {{expected 'match' clause on}}
 #pragma omp declare variant(foo) // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foo) // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foo) xxx // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
@@ -41,7 +41,7 @@
 #pragma omp declare variant(foo) match(device={kind(}) // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind()}) // expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}}
 #pragma omp declare variant(foo) match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}}
-#pragma omp declare variant(foo) match(device={kind(score( ibm)}) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
+#pragma omp declare variant(foo) match(device={kind(score( ibm)}) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<recovery-expr>()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp declare variant(foo) match(device={kind(score(foo()) ibm)}) // expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('foo()'); score ignored}} expected-warning {{'ibm' is not a valid context property for the context selector 'kind' and the context set 'device'; property ignored}} expected-note {{try 'match(implementation={vendor(ibm)})'}} expected-note {{the ignored property spans until here}}
 #pragma omp declare variant(foo) match(device={kind(score(5): host), kind(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'kind' was used already in the same 'omp declare variant' directive; selector ignored}} expected-note {{the previous context selector 'kind' used here}} expected-note {{the ignored selector spans until here}}
Index: clang/test/OpenMP/begin_declare_variant_messages.c
===================================================================
--- clang/test/OpenMP/begin_declare_variant_messages.c
+++ clang/test/OpenMP/begin_declare_variant_messages.c
@@ -80,7 +80,7 @@
 #pragma omp end declare variant
 #pragma omp begin declare variant match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}}
 #pragma omp end declare variant
-#pragma omp begin declare variant match(device={kind(score( ibm)}) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<invalid>'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
+#pragma omp begin declare variant match(device={kind(score( ibm)}) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('<recovery-expr>()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp end declare variant
 #pragma omp begin declare variant match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}}
 #pragma omp end declare variant
Index: clang/test/Index/complete-switch.c
===================================================================
--- clang/test/Index/complete-switch.c
+++ clang/test/Index/complete-switch.c
@@ -6,5 +6,5 @@
   }
 }
 
-// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty
+// RUN: not %clang_cc1 -fsyntax-only -Xclang -fno-recovery-ast -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty
 // CHECK-NOT: COMPLETION: foo
Index: clang/test/CodeGen/builtins-systemz-zvector3-error.c
===================================================================
--- clang/test/CodeGen/builtins-systemz-zvector3-error.c
+++ clang/test/CodeGen/builtins-systemz-zvector3-error.c
@@ -60,65 +60,85 @@
 int cc;
 
 void test_integer(void) {
-  vsc = vec_sldb(vsc, vsc, idx); // expected-error {{no matching function}}
+  vsc = vec_sldb(vsc, vsc, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vuc = vec_sldb(vuc, vuc, idx); // expected-error {{no matching function}}
+  vuc = vec_sldb(vuc, vuc, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vss = vec_sldb(vss, vss, idx); // expected-error {{no matching function}}
+  vss = vec_sldb(vss, vss, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vus = vec_sldb(vus, vus, idx); // expected-error {{no matching function}}
+  vus = vec_sldb(vus, vus, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vsi = vec_sldb(vsi, vsi, idx); // expected-error {{no matching function}}
+  vsi = vec_sldb(vsi, vsi, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vui = vec_sldb(vui, vui, idx); // expected-error {{no matching function}}
+  vui = vec_sldb(vui, vui, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vsl = vec_sldb(vsl, vsl, idx); // expected-error {{no matching function}}
+  vsl = vec_sldb(vsl, vsl, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vul = vec_sldb(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_sldb(vul, vul, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vf = vec_sldb(vf, vf, idx);    // expected-error {{no matching function}}
+  vf = vec_sldb(vf, vf, idx);    // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vd = vec_sldb(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_sldb(vd, vd, idx);    // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsld' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
 
-  vsc = vec_srdb(vsc, vsc, idx); // expected-error {{no matching function}}
+  vsc = vec_srdb(vsc, vsc, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vuc = vec_srdb(vuc, vuc, idx); // expected-error {{no matching function}}
+  vuc = vec_srdb(vuc, vuc, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vss = vec_srdb(vss, vss, idx); // expected-error {{no matching function}}
+  vss = vec_srdb(vss, vss, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vus = vec_srdb(vus, vus, idx); // expected-error {{no matching function}}
+  vus = vec_srdb(vus, vus, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vsi = vec_srdb(vsi, vsi, idx); // expected-error {{no matching function}}
+  vsi = vec_srdb(vsi, vsi, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vui = vec_srdb(vui, vui, idx); // expected-error {{no matching function}}
+  vui = vec_srdb(vui, vui, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vsl = vec_srdb(vsl, vsl, idx); // expected-error {{no matching function}}
+  vsl = vec_srdb(vsl, vsl, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vul = vec_srdb(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_srdb(vul, vul, idx); // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vf = vec_srdb(vf, vf, idx);    // expected-error {{no matching function}}
+  vf = vec_srdb(vf, vf, idx);    // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
-  vd = vec_srdb(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_srdb(vd, vd, idx);    // expected-error {{no matching function}} \
+                                 // expected-error {{argument to '__builtin_s390_vsrd' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 9 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 7}}
 }
Index: clang/test/CodeGen/builtins-systemz-zvector2-error.c
===================================================================
--- clang/test/CodeGen/builtins-systemz-zvector2-error.c
+++ clang/test/CodeGen/builtins-systemz-zvector2-error.c
@@ -119,10 +119,10 @@
 }
 
 void test_integer(void) {
-  vf = vec_sld(vf, vf, idx);    // expected-error {{no matching function}}
+  vf = vec_sld(vf, vf, idx);    // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vd = vec_sld(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_sld(vd, vd, idx);    // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
 
@@ -132,22 +132,22 @@
 }
 
 void test_float(void) {
-  vbi = vec_fp_test_data_class(vf, idx, &cc);   // expected-error {{no matching function}}
+  vbi = vec_fp_test_data_class(vf, idx, &cc);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vftcisb' must be a constant integer}} expected-error {{argument to '__builtin_s390_vftcidb' must be a constant integer}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
-  vbi = vec_fp_test_data_class(vf, -1, &cc);    // expected-error {{no matching function}}
+  vbi = vec_fp_test_data_class(vf, -1, &cc);    // expected-error {{no matching function}} expected-error 2{{argument value -1 is outside the valid range [0, 4095]}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
-  vbi = vec_fp_test_data_class(vf, 4096, &cc);  // expected-error {{no matching function}}
+  vbi = vec_fp_test_data_class(vf, 4096, &cc);  // expected-error {{no matching function}} expected-error 2{{argument value 4096 is outside the valid range [0, 4095]}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
-  vbl = vec_fp_test_data_class(vd, idx, &cc);   // expected-error {{no matching function}}
+  vbl = vec_fp_test_data_class(vd, idx, &cc);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vftcisb' must be a constant integer}} expected-error {{argument to '__builtin_s390_vftcidb' must be a constant integer}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
-  vbl = vec_fp_test_data_class(vd, -1, &cc);    // expected-error {{no matching function}}
+  vbl = vec_fp_test_data_class(vd, -1, &cc);    // expected-error {{no matching function}} expected-error 2{{argument value -1 is outside the valid range [0, 4095]}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
-  vbl = vec_fp_test_data_class(vd, 4096, &cc);  // expected-error {{no matching function}}
+  vbl = vec_fp_test_data_class(vd, 4096, &cc);  // expected-error {{no matching function}} expected-error 2{{argument value 4096 is outside the valid range [0, 4095]}}
                                                 // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
                                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
 }
Index: clang/test/CodeGen/builtins-systemz-zvector-error.c
===================================================================
--- clang/test/CodeGen/builtins-systemz-zvector-error.c
+++ clang/test/CodeGen/builtins-systemz-zvector-error.c
@@ -67,7 +67,7 @@
   len = __lcbb(cptr, 8192);  // expected-error {{no matching function}}
                              // expected-note@vecintrin.h:* {{must be a constant power of 2 from 64 to 4096}}
 
-  vsl = vec_permi(vsl, vsl, idx); // expected-error {{no matching function}}
+  vsl = vec_permi(vsl, vsl, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vpdi' must be a constant integer}}
                                   // expected-note@vecintrin.h:* 3 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
   vsl = vec_permi(vsl, vsl, -1);  // expected-error {{no matching function}}
@@ -76,7 +76,7 @@
   vsl = vec_permi(vsl, vsl, 4);   // expected-error {{no matching function}}
                                   // expected-note@vecintrin.h:* 3 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vul = vec_permi(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_permi(vul, vul, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vpdi' must be a constant integer}}
                                   // expected-note@vecintrin.h:* 2 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 3}}
   vul = vec_permi(vul, vul, -1);  // expected-error {{no matching function}}
@@ -85,7 +85,7 @@
   vul = vec_permi(vul, vul, 4);   // expected-error {{no matching function}}
                                   // expected-note@vecintrin.h:* 2 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 3}}
-  vbl = vec_permi(vbl, vbl, idx); // expected-error {{no matching function}}
+  vbl = vec_permi(vbl, vbl, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vpdi' must be a constant integer}}
                                   // expected-note@vecintrin.h:* 2 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 3}}
   vbl = vec_permi(vbl, vbl, -1);  // expected-error {{no matching function}}
@@ -94,7 +94,7 @@
   vbl = vec_permi(vbl, vbl, 4);   // expected-error {{no matching function}}
                                   // expected-note@vecintrin.h:* 2 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 3}}
-  vd = vec_permi(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_permi(vd, vd, idx);    // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vpdi' must be a constant integer}}
                                   // expected-note@vecintrin.h:* 3 {{candidate function not viable}}
                                   // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
   vd = vec_permi(vd, vd, -1);     // expected-error {{no matching function}}
@@ -232,27 +232,27 @@
                                              // expected-note@vecintrin.h:* 6 {{candidate function not viable}}
                                              // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
 
-  vsc = vec_load_bndry(cptrsc, idx);   // expected-error {{no matching function}}
+  vsc = vec_load_bndry(cptrsc, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vsc = vec_load_bndry(cptrsc, 200);   // expected-error {{no matching function}}
+  vsc = vec_load_bndry(cptrsc, 200);   // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vsc = vec_load_bndry(cptrsc, 32);    // expected-error {{no matching function}}
+  vsc = vec_load_bndry(cptrsc, 32);    // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vsc = vec_load_bndry(cptrsc, 8192);  // expected-error {{no matching function}}
+  vsc = vec_load_bndry(cptrsc, 8192);  // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vuc = vec_load_bndry(cptruc, idx);   // expected-error {{no matching function}}
+  vuc = vec_load_bndry(cptruc, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vss = vec_load_bndry(cptrss, idx);   // expected-error {{no matching function}}
+  vss = vec_load_bndry(cptrss, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vus = vec_load_bndry(cptrus, idx);   // expected-error {{no matching function}}
+  vus = vec_load_bndry(cptrus, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vsi = vec_load_bndry(cptrsi, idx);   // expected-error {{no matching function}}
+  vsi = vec_load_bndry(cptrsi, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vui = vec_load_bndry(cptrui, idx);   // expected-error {{no matching function}}
+  vui = vec_load_bndry(cptrui, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vsl = vec_load_bndry(cptrsl, idx);   // expected-error {{no matching function}}
+  vsl = vec_load_bndry(cptrsl, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
-  vul = vec_load_bndry(cptrul, idx);   // expected-error {{no matching function}}
+  vul = vec_load_bndry(cptrul, idx);   // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vlbb' must be a constant integer}}
                                        // expected-note@vecintrin.h:* 9 {{must be a constant power of 2 from 64 to 4096}}
 
   vuc = vec_genmask(idx);  // expected-error {{no matching function}}
@@ -420,108 +420,140 @@
 }
 
 void test_integer(void) {
-  vsc = vec_rl_mask(vsc, vuc, idx); // expected-error {{no matching function}}
+  vsc = vec_rl_mask(vsc, vuc, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vuc = vec_rl_mask(vuc, vuc, idx); // expected-error {{no matching function}}
+  vuc = vec_rl_mask(vuc, vuc, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vss = vec_rl_mask(vss, vus, idx); // expected-error {{no matching function}}
+  vss = vec_rl_mask(vss, vus, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vus = vec_rl_mask(vus, vus, idx); // expected-error {{no matching function}}
+  vus = vec_rl_mask(vus, vus, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vsi = vec_rl_mask(vsi, vui, idx); // expected-error {{no matching function}}
+  vsi = vec_rl_mask(vsi, vui, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vui = vec_rl_mask(vui, vui, idx); // expected-error {{no matching function}}
+  vui = vec_rl_mask(vui, vui, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vsl = vec_rl_mask(vsl, vul, idx); // expected-error {{no matching function}}
+  vsl = vec_rl_mask(vsl, vul, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
-  vul = vec_rl_mask(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_rl_mask(vul, vul, idx); // expected-error {{no matching function}} \
+                                    // expected-error {{argument to '__builtin_s390_verimb' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimh' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimf' must be a constant integer}} \
+                                    // expected-error {{argument to '__builtin_s390_verimg' must be a constant integer}}
                                     // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
                                     // expected-note@vecintrin.h:* 1 {{must be a constant integer}}
 
-  vsc = vec_sld(vsc, vsc, idx); // expected-error {{no matching function}}
+  vsc = vec_sld(vsc, vsc, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vsc = vec_sld(vsc, vsc, -1);  // expected-error {{no matching function}}
+  vsc = vec_sld(vsc, vsc, -1);  // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vsc = vec_sld(vsc, vsc, 16);  // expected-error {{no matching function}}
+  vsc = vec_sld(vsc, vsc, 16);  // expected-error {{no matching function}} expected-error {{argument value 16 is outside the valid range [0, 15]}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vuc = vec_sld(vuc, vuc, idx); // expected-error {{no matching function}}
+  vuc = vec_sld(vuc, vuc, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vuc = vec_sld(vuc, vuc, -1);  // expected-error {{no matching function}}
+  vuc = vec_sld(vuc, vuc, -1);  // expected-error {{no matching function}} expected-error {{argument value -1 is outside the valid range [0, 15]}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vuc = vec_sld(vuc, vuc, 16);  // expected-error {{no matching function}}
+  vuc = vec_sld(vuc, vuc, 16);  // expected-error {{no matching function}} expected-error {{argument value 16 is outside the valid range [0, 15]}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vss = vec_sld(vss, vss, idx); // expected-error {{no matching function}}
+  vss = vec_sld(vss, vss, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vus = vec_sld(vus, vus, idx); // expected-error {{no matching function}}
+  vus = vec_sld(vus, vus, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vsi = vec_sld(vsi, vsi, idx); // expected-error {{no matching function}}
+  vsi = vec_sld(vsi, vsi, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vui = vec_sld(vui, vui, idx); // expected-error {{no matching function}}
+  vui = vec_sld(vui, vui, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vsl = vec_sld(vsl, vsl, idx); // expected-error {{no matching function}}
+  vsl = vec_sld(vsl, vsl, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
-  vul = vec_sld(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_sld(vul, vul, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
-  vd = vec_sld(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_sld(vd, vd, idx);    // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                 // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
                                 // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
 
-  vsc = vec_sldw(vsc, vsc, idx); // expected-error {{no matching function}}
+  vsc = vec_sldw(vsc, vsc, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vsc = vec_sldw(vsc, vsc, -1);  // expected-error {{no matching function}}
+  vsc = vec_sldw(vsc, vsc, -1);  // expected-error {{no matching function}} expected-error {{argument value -4 is outside the valid range [0, 15]}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vsc = vec_sldw(vsc, vsc, 4);   // expected-error {{no matching function}}
+  vsc = vec_sldw(vsc, vsc, 4);   // expected-error {{no matching function}} expected-error {{argument value 16 is outside the valid range [0, 15]}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vuc = vec_sldw(vuc, vuc, idx); // expected-error {{no matching function}}
+  vuc = vec_sldw(vuc, vuc, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vuc = vec_sldw(vuc, vuc, -1);  // expected-error {{no matching function}}
+  vuc = vec_sldw(vuc, vuc, -1);  // expected-error {{no matching function}} expected-error {{argument value -4 is outside the valid range [0, 15]}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vuc = vec_sldw(vuc, vuc, 4);   // expected-error {{no matching function}}
+  vuc = vec_sldw(vuc, vuc, 4);   // expected-error {{no matching function}} expected-error {{argument value 16 is outside the valid range [0, 15]}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vss = vec_sldw(vss, vss, idx); // expected-error {{no matching function}}
+  vss = vec_sldw(vss, vss, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vus = vec_sldw(vus, vus, idx); // expected-error {{no matching function}}
+  vus = vec_sldw(vus, vus, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vsi = vec_sldw(vsi, vsi, idx); // expected-error {{no matching function}}
+  vsi = vec_sldw(vsi, vsi, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vui = vec_sldw(vui, vui, idx); // expected-error {{no matching function}}
+  vui = vec_sldw(vui, vui, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vsl = vec_sldw(vsl, vsl, idx); // expected-error {{no matching function}}
+  vsl = vec_sldw(vsl, vsl, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vul = vec_sldw(vul, vul, idx); // expected-error {{no matching function}}
+  vul = vec_sldw(vul, vul, idx); // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
-  vd = vec_sldw(vd, vd, idx);    // expected-error {{no matching function}}
+  vd = vec_sldw(vd, vd, idx);    // expected-error {{no matching function}} expected-error {{argument to '__builtin_s390_vsldb' must be a constant integer}}
                                  // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
                                  // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
 }
Index: clang/test/CodeGen/builtins-ppc-error.c
===================================================================
--- clang/test/CodeGen/builtins-ppc-error.c
+++ clang/test/CodeGen/builtins-ppc-error.c
@@ -48,8 +48,8 @@
 }
 
 void testCTF(int index) {
-  vec_ctf(vsi, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}}
-  vec_ctf(vui, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}}
+  vec_ctf(vsi, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}} expected-error {{argument to '__builtin_altivec_vcfux' must be a constant integer}}
+  vec_ctf(vui, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}} expected-error {{argument to '__builtin_altivec_vcfux' must be a constant integer}}
 }
 
 void testVCFSX(int index) {
Index: clang/test/AST/ast-dump-recovery.c
===================================================================
--- clang/test/AST/ast-dump-recovery.c
+++ clang/test/AST/ast-dump-recovery.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -fc-dependence -ast-dump %s | FileCheck -strict-whitespace %s
 
 int some_func(int);
 
@@ -24,14 +24,10 @@
 int unary_address = &(a + 1);
 
 // CHECK:       VarDecl {{.*}} ternary 'int' cinit
-// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:  `-ConditionalOperator {{.*}}
 // CHECK-NEXT:    |-DeclRefExpr {{.*}} 'a'
-// CHECK-NEXT:    |-TypoExpr {{.*}}
+// CHECK-NEXT:    |-RecoveryExpr {{.*}}
 // CHECK-NEXT:    `-DeclRefExpr {{.*}} 'a'
-// FIXME: The TypoExpr should never be print, and should be downgraded to
-// RecoveryExpr -- typo correction is performed too early in C-only codepath,
-// which makes no correction when clang finishes the full expr (Sema::Sema::ActOnFinishFullExpr).
-// this will be fixed when we support dependent mechanism and delayed typo correction for C.
 int ternary = a ? undef : a;
 
 void test1() {
@@ -42,11 +38,31 @@
 
 void test2() {
   int* ptr;
-  // FIXME: the top-level expr should be a binary operator.
-  // CHECK:      ImplicitCastExpr {{.*}} contains-errors <LValueToRValue>
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors lvalue
-  // CHECK-NEXT:   |-DeclRefExpr {{.*}} 'ptr' 'int *'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}}
-  // CHECK-NEXT:     `-DeclRefExpr {{.*}} 'some_func'
+  // CHECK:     BinaryOperator {{.*}} contains-errors '='
+  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *'
+  // CHECK-NEXT: `-RecoveryExpr {{.*}}
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
   ptr = some_func(); // should not crash
+
+  int compoundOp;
+  // CHECK:     CompoundAssignOperator {{.*}} '+='
+  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'compoundOp'
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+  compoundOp += some_func();
+}
+
+void test3() {
+  // CHECK:      CallExpr {{.*}} '<dependent type>' contains-errors
+  // CHECK-NEXT:  |-ParenExpr {{.*}} contains-errors lvalue
+  // CHECK-NEXT:  | `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  |   `-DeclRefExpr {{.*}} '__builtin_classify_type'
+  // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
+  (*__builtin_classify_type)(1);
+
+  extern void ext();
+  // FIXME: the broken AST will be preserved once we remove the early typo correction
+  // in Sema::CheckPlaceholderExpr.
+  // CHECK-NOT: DeclRefExpr {{.*}} 'ext' 'int (int)'
+  ext(undef_var);
 }
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -13291,18 +13291,8 @@
   // If either side is type-dependent, create an appropriate dependent
   // expression.
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
-    if (Fns.empty()) {
-      // If there are no functions to store, just build a dependent
-      // BinaryOperator or CompoundAssignment.
-      if (Opc <= BO_Assign || Opc > BO_OrAssign)
-        return BinaryOperator::Create(
-            Context, Args[0], Args[1], Opc, Context.DependentTy, VK_RValue,
-            OK_Ordinary, OpLoc, CurFPFeatureOverrides());
-      return CompoundAssignOperator::Create(
-          Context, Args[0], Args[1], Opc, Context.DependentTy, VK_LValue,
-          OK_Ordinary, OpLoc, CurFPFeatureOverrides(), Context.DependentTy,
-          Context.DependentTy);
-    }
+    if (Fns.empty())
+      return CreateDependentBinOp(OpLoc, Opc, Args[0], Args[1]);
 
     // FIXME: save results of ADL from here?
     CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -46,6 +46,7 @@
 #include "clang/Sema/SemaFixItUtils.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/SaveAndRestore.h"
 using namespace clang;
@@ -6431,6 +6432,17 @@
     checkDirectCallValidity(*this, Fn, FD, ArgExprs);
   }
 
+  if (getLangOpts().CDependence &&
+      (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs))) {
+    assert(!getLangOpts().CPlusPlus);
+    assert(Fn->containsErrors() ||
+           llvm::any_of(ArgExprs,
+                        [](clang::Expr *E) { return E->containsErrors(); }) &&
+               "should only occur in error-recovery path.");
+    return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
+                            VK_RValue, RParenLoc, CurFPFeatureOverrides());
+  }
+
   return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc,
                                ExecConfig, IsExecConfig);
 }
@@ -6571,7 +6583,7 @@
                          CurFPFeatureOverrides(), NumParams, UsesADL);
   }
 
-  if (!getLangOpts().CPlusPlus) {
+  if (!getLangOpts().CPlusPlus && !getLangOpts().CDependence) {
     // Forget about the nulled arguments since typo correction
     // do not handle them well.
     TheCall->shrinkNumArgs(Args.size());
@@ -8059,6 +8071,16 @@
   VK = VK_RValue;
   OK = OK_Ordinary;
 
+  if (getLangOpts().CDependence &&
+      (Cond.get()->isTypeDependent() || LHS.get()->isTypeDependent() ||
+       RHS.get()->isTypeDependent())) {
+    assert(!getLangOpts().CPlusPlus);
+    assert(Cond.get()->containsErrors() || LHS.get()->containsErrors() ||
+           RHS.get()->containsErrors() &&
+               "should only occur in error-recovery path.");
+    return Context.DependentTy;
+  }
+
   // The OpenCL operator with a vector condition is sufficiently
   // different to merit its own checker.
   if ((getLangOpts().OpenCL && Cond.get()->getType()->isVectorType()) ||
@@ -8525,7 +8547,7 @@
                                     SourceLocation ColonLoc,
                                     Expr *CondExpr, Expr *LHSExpr,
                                     Expr *RHSExpr) {
-  if (!getLangOpts().CPlusPlus) {
+  if (!getLangOpts().CPlusPlus && !Context.getLangOpts().CDependence) {
     // C cannot handle TypoExpr nodes in the condition because it
     // doesn't handle dependent types properly, so make sure any TypoExprs have
     // been dealt with before checking the operands.
@@ -13641,7 +13663,7 @@
 CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr,
                            Expr *RHSExpr) {
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
-  if (!S.getLangOpts().CPlusPlus) {
+  if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().CDependence) {
     // C cannot handle TypoExpr nodes on either side of a binop because it
     // doesn't handle dependent types properly, so make sure any TypoExprs have
     // been dealt with before checking the operands.
@@ -14220,6 +14242,21 @@
   return S.CreateOverloadedBinOp(OpLoc, Opc, Functions, LHS, RHS);
 }
 
+ExprResult Sema::CreateDependentBinOp(SourceLocation OpLoc,
+                                      BinaryOperatorKind Opc, Expr *LHS,
+                                      Expr *RHS) {
+  assert(LHS->isTypeDependent() || RHS->isTypeDependent());
+  // If there are no functions to store, just build a dependent
+  // BinaryOperator or CompoundAssignment.
+  if (Opc <= BO_Assign || Opc > BO_OrAssign)
+    return BinaryOperator::Create(Context, LHS, RHS, Opc, Context.DependentTy,
+                                  VK_RValue, OK_Ordinary, OpLoc,
+                                  CurFPFeatureOverrides());
+  return CompoundAssignOperator::Create(
+      Context, LHS, RHS, Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
+      OpLoc, CurFPFeatureOverrides(), Context.DependentTy, Context.DependentTy);
+}
+
 ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                             BinaryOperatorKind Opc,
                             Expr *LHSExpr, Expr *RHSExpr) {
@@ -14322,6 +14359,14 @@
       return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
   }
 
+  if (getLangOpts().CDependence &&
+      (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())) {
+    assert(!getLangOpts().CPlusPlus);
+    assert((LHSExpr->containsErrors() || RHSExpr->containsErrors()) &&
+           "Should only occur in error-recovery path.");
+    return CreateDependentBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
+  }
+
   // Build a built-in binary operation.
   return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
 }
@@ -19000,7 +19045,7 @@
 /// Check for operands with placeholder types and complain if found.
 /// Returns ExprError() if there was an error and no recovery was possible.
 ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
-  if (!getLangOpts().CPlusPlus) {
+  if (!getLangOpts().CPlusPlus && !Context.getLangOpts().CDependence) {
     // C cannot handle TypoExpr nodes on either side of a binop because it
     // doesn't handle dependent types properly, so make sure any TypoExprs have
     // been dealt with before checking the operands.
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2688,6 +2688,16 @@
     return;
   }
 
+  if (Self.getLangOpts().CDependence &&
+      (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
+       SrcExpr.get()->isValueDependent())) {
+    assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||
+            SrcExpr.get()->containsErrors()) &&
+           "should only occur in error-recovery path.");
+    assert(Kind == CK_Dependent);
+    return;
+  }
+
   // Overloads are allowed with C extensions, so we need to support them.
   if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
     DeclAccessPair DAP;
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -653,7 +653,7 @@
       }
       // In this case, ActOnBinOp or ActOnConditionalOp performed the
       // CorrectDelayedTyposInExpr check.
-      if (!getLangOpts().CPlusPlus)
+      if (!getLangOpts().CPlusPlus && !Actions.Context.getLangOpts().CDependence)
         continue;
     }
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2923,9 +2923,11 @@
       !Args.hasArg(OPT_fno_concept_satisfaction_caching);
   if (Args.hasArg(OPT_fconcepts_ts))
     Diags.Report(diag::warn_fe_concepts_ts_flag);
+  Opts.CDependence =
+      Args.hasFlag(OPT_fc_dependence, OPT_fno_c_dependence, true);
   // Recovery AST still heavily relies on dependent-type machinery.
   Opts.RecoveryAST =
-      Args.hasFlag(OPT_frecovery_ast, OPT_fno_recovery_ast, Opts.CPlusPlus);
+      Args.hasFlag(OPT_frecovery_ast, OPT_fno_recovery_ast, true);
   Opts.RecoveryASTType =
       Args.hasFlag(OPT_frecovery_ast_type, OPT_fno_recovery_ast_type, false);
   Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -3754,7 +3754,8 @@
     case NPC_NeverValueDependent:
       llvm_unreachable("Unexpected value dependent expression!");
     case NPC_ValueDependentIsNull:
-      if (isTypeDependent() || getType()->isIntegralType(Ctx))
+      if ((!containsErrors() && isTypeDependent()) ||
+          getType()->isIntegralType(Ctx))
         return NPCK_ZeroExpression;
       else
         return NPCK_NotNull;
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -5166,6 +5166,8 @@
                         BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr);
   ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc,
                                 Expr *LHSExpr, Expr *RHSExpr);
+  ExprResult CreateDependentBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc,
+                                  Expr *LHS, Expr *RHS);
 
   void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc);
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4026,6 +4026,10 @@
           "(experimental)">;
 def fno_recovery_ast_type : Flag<["-"], "fno-recovery-ast-type">;
 
+def fc_dependence : Flag<["-"], "fc-dependence">,
+  HelpText<"Build dependent AST nodes in C for error recovery">;
+def fno_c_dependence : Flag<["-"], "fno-c-dependence">;
+
 let Group = Action_Group in {
 
 def Eonly : Flag<["-"], "Eonly">,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -150,6 +150,7 @@
 
 COMPATIBLE_LANGOPT(RecoveryAST, 1, 0, "Preserve expressions in AST when encountering errors")
 COMPATIBLE_LANGOPT(RecoveryASTType, 1, 0, "Preserve the type in recovery expressions")
+COMPATIBLE_LANGOPT(CDependence, 1, 0, "Build dependent AST nodes in C for better error recovery")
 
 BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
 LANGOPT(POSIXThreads      , 1, 0, "POSIX thread support")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D85025: [... Haojian Wu via Phabricator via cfe-commits

Reply via email to