Hi!

This patch does a few things:
1) replaces ICEs with diagnostics + return false in
   potential_constant_expression_1 for OpenMP/OpenACC/Cilk+ constructs,
   I believe unless the upcoming versions of those standards say otherwise,
   we should treat the constructs as invalid in constexpr
When writing a testcase for 1), I've noticed very odd locus for all the
error messages, so I've changed
2) all but one error in potential_constant_expression_1 to error_at with
location_of (t)
and finally
3) #pragma omp target/teams in some cases had wrong locus too

While 1) and 3) I think I can commit with my OpenMP maintainer hat on,
I'm seeking approval for 2).

The only spot in potential_constant_expression_1 I've kept error
is for division by zero, which breaks several g++.dg/warn/overflow-warn*.C
tests and I have no idea what's going on in dejagnu there (both patched
and unpatched compilers emit 4 different diagnostics on a single line
there, the difference is just in one of those diagnostics (different
column), but the testcases actually try to match only 3 diagnostics and
the wording of some of them is very similar and one of the expected
diagnostics is pruned somewhere during the dejagnu processing).
After fighting with that for a while I gave up.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-02-22  Jakub Jelinek  <ja...@redhat.com>

        PR c++/79664
        * parser.c (cp_parser_omp_teams, cp_parser_omp_target): Use
        SET_EXPR_LOCATION on OMP_TARGET/OMP_TEAMS tree.
        * constexpr.c (potential_constant_expression_1): Handle
        OMP_*, OACC_* and CILK_* trees.  Use error_at with location_of (t)
        instead of error, use location_of (t) instead of
        EXPR_LOC_OR_LOC (t, input_location).

        * g++.dg/gomp/teams-1.C: Adjust expected diagnostic location.
        * g++.dg/cpp1y/constexpr-throw.C: Likewise.
        * g++.dg/gomp/pr79664.C: New test.

--- gcc/cp/parser.c.jj  2017-02-20 13:43:21.000000000 +0100
+++ gcc/cp/parser.c     2017-02-22 17:17:39.176918357 +0100
@@ -35519,6 +35519,7 @@ cp_parser_omp_teams (cp_parser *parser,
          OMP_TEAMS_CLAUSES (ret) = clauses;
          OMP_TEAMS_BODY (ret) = body;
          OMP_TEAMS_COMBINED (ret) = 1;
+         SET_EXPR_LOCATION (ret, loc);
          return add_stmt (ret);
        }
     }
@@ -35540,6 +35541,7 @@ cp_parser_omp_teams (cp_parser *parser,
   TREE_TYPE (stmt) = void_type_node;
   OMP_TEAMS_CLAUSES (stmt) = clauses;
   OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
+  SET_EXPR_LOCATION (stmt, loc);
 
   return add_stmt (stmt);
 }
@@ -35958,6 +35960,7 @@ cp_parser_omp_target (cp_parser *parser,
          OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
          OMP_TARGET_BODY (stmt) = body;
          OMP_TARGET_COMBINED (stmt) = 1;
+         SET_EXPR_LOCATION (stmt, pragma_tok->location);
          add_stmt (stmt);
          pc = &OMP_TARGET_CLAUSES (stmt);
          goto check_clauses;
--- gcc/cp/constexpr.c.jj       2017-02-21 18:56:43.000000000 +0100
+++ gcc/cp/constexpr.c  2017-02-22 17:16:53.413507546 +0100
@@ -5004,7 +5004,8 @@ potential_constant_expression_1 (tree t,
   if (TREE_THIS_VOLATILE (t) && !DECL_P (t))
     {
       if (flags & tf_error)
-        error ("expression %qE has side-effects", t);
+        error_at (location_of (t),
+                 "expression %qE has side-effects", t);
       return false;
     }
   if (CONSTANT_CLASS_P (t))
@@ -5086,7 +5087,7 @@ potential_constant_expression_1 (tree t,
              {
                /* fold_call_expr can't do anything with IFN calls.  */
                if (flags & tf_error)
-                 error_at (EXPR_LOC_OR_LOC (t, input_location),
+                 error_at (location_of (t),
                            "call to internal function %qE", t);
                return false;
              }
@@ -5105,7 +5106,7 @@ potential_constant_expression_1 (tree t,
                  {
                    if (flags & tf_error)
                      {
-                       error_at (EXPR_LOC_OR_LOC (t, input_location),
+                       error_at (location_of (t),
                                  "call to non-constexpr function %qD", fun);
                        explain_invalid_constexpr_fn (fun);
                      }
@@ -5199,7 +5200,7 @@ potential_constant_expression_1 (tree t,
            && !integer_zerop (from))
          {
            if (flags & tf_error)
-             error_at (EXPR_LOC_OR_LOC (t, input_location),
+             error_at (location_of (t),
                        "reinterpret_cast from integer to pointer");
            return false;
          }
@@ -5266,7 +5267,8 @@ potential_constant_expression_1 (tree t,
                && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x)))
              {
                if (flags & tf_error)
-                 error ("use of %<this%> in a constant expression");
+                 error_at (location_of (t),
+                           "use of %<this%> in a constant expression");
                return false;
              }
            return true;
@@ -5354,10 +5356,40 @@ potential_constant_expression_1 (tree t,
     case DELETE_EXPR:
     case VEC_DELETE_EXPR:
     case THROW_EXPR:
+    case OMP_PARALLEL:
+    case OMP_TASK:
+    case OMP_FOR:
+    case OMP_DISTRIBUTE:
+    case OMP_TASKLOOP:
+    case OMP_TEAMS:
+    case OMP_TARGET_DATA:
+    case OMP_TARGET:
+    case OMP_SECTIONS:
+    case OMP_ORDERED:
+    case OMP_CRITICAL:
+    case OMP_SINGLE:
+    case OMP_SECTION:
+    case OMP_MASTER:
+    case OMP_TASKGROUP:
+    case OMP_TARGET_UPDATE:
+    case OMP_TARGET_ENTER_DATA:
+    case OMP_TARGET_EXIT_DATA:
     case OMP_ATOMIC:
     case OMP_ATOMIC_READ:
     case OMP_ATOMIC_CAPTURE_OLD:
     case OMP_ATOMIC_CAPTURE_NEW:
+    case OACC_PARALLEL:
+    case OACC_KERNELS:
+    case OACC_DATA:
+    case OACC_HOST_DATA:
+    case OACC_LOOP:
+    case OACC_CACHE:
+    case OACC_DECLARE:
+    case OACC_ENTER_DATA:
+    case OACC_EXIT_DATA:
+    case OACC_UPDATE:
+    case CILK_SIMD:
+    case CILK_FOR:
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
     case OBJ_TYPE_REF:
@@ -5366,7 +5398,8 @@ potential_constant_expression_1 (tree t,
     case AT_ENCODE_EXPR:
     fail:
       if (flags & tf_error)
-       error ("expression %qE is not a constant expression", t);
+       error_at (location_of (t),
+                 "expression %qE is not a constant expression", t);
       return false;
 
     case TYPEID_EXPR:
@@ -5378,8 +5411,9 @@ potential_constant_expression_1 (tree t,
            && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
           {
             if (flags & tf_error)
-              error ("typeid-expression is not a constant expression "
-                     "because %qE is of polymorphic type", e);
+              error_at (location_of (t),
+                       "typeid-expression is not a constant expression "
+                       "because %qE is of polymorphic type", e);
             return false;
           }
         return true;
@@ -5438,8 +5472,9 @@ potential_constant_expression_1 (tree t,
           constant expression.  */
        {
          if (flags & tf_error)
-           error ("cast to non-integral type %qT in a constant expression",
-                  TREE_TYPE (t));
+           error_at (location_of (t),
+                     "cast to non-integral type %qT in a constant expression",
+                     TREE_TYPE (t));
          return false;
        }
 
@@ -5504,8 +5539,9 @@ potential_constant_expression_1 (tree t,
        {
          if (flags & tf_error)
            {
-             error ("temporary of non-literal type %qT in a "
-                    "constant expression", TREE_TYPE (t));
+             error_at (location_of (t),
+                       "temporary of non-literal type %qT in a "
+                       "constant expression", TREE_TYPE (t));
              explain_non_literal_class (TREE_TYPE (t));
            }
          return false;
@@ -5681,7 +5717,8 @@ potential_constant_expression_1 (tree t,
                                             want_rval, strict, tf_none))
          return true;
       if (flags & tf_error)
-       error ("expression %qE is not a constant expression", t);
+       error_at (location_of (t),
+                 "expression %qE is not a constant expression", t);
       return false;
 
     case VEC_INIT_EXPR:
@@ -5689,7 +5726,8 @@ potential_constant_expression_1 (tree t,
        return true;
       if (flags & tf_error)
        {
-         error ("non-constant array initialization");
+         error_at (location_of (t),
+                   "non-constant array initialization");
          diagnose_non_constexpr_vec_init (t);
        }
       return false;
@@ -5710,7 +5748,8 @@ potential_constant_expression_1 (tree t,
        if (breaks (target) || continues (target))
          return true;
        if (flags & tf_error)
-         error ("%<goto%> is not a constant expression");
+         error_at (location_of (t),
+                   "%<goto%> is not a constant expression");
        return false;
       }
 
--- gcc/testsuite/g++.dg/gomp/teams-1.C.jj      2016-05-24 10:56:00.000000000 
+0200
+++ gcc/testsuite/g++.dg/gomp/teams-1.C 2017-02-22 17:20:18.310869557 +0100
@@ -26,7 +26,7 @@ foo (int x)
   {
   #pragma omp target teams
     { case 0:; }               // { dg-error "jump" }
-                               // { dg-warning "statement will never be 
executed" "" { target *-*-* } 28 }
+                               // { dg-warning "statement will never be 
executed" "" { target *-*-* } 27 }
                                 // { dg-message "enters" "" { target *-*-* } 
28 }
   }
 }
--- gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C.jj     2016-08-06 
12:11:32.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C        2017-02-22 
16:42:55.605778417 +0100
@@ -7,19 +7,19 @@ constexpr void f1() {
 
 constexpr void f2() {
   if (true)
-    throw;
-} // { dg-error "not a constant expression" }
+    throw;     // { dg-error "not a constant expression" }
+}
 
 constexpr void f3() {
   if (false)
     ;
   else
-    throw;
-}// { dg-error "not a constant expression" }
+    throw;     // { dg-error "not a constant expression" }
+}
 
 constexpr void f4() {
-  throw;
-}// { dg-error "not a constant expression" }
+  throw;       // { dg-error "not a constant expression" }
+}
 
 constexpr int fun(int n) {
   switch (n) {
--- gcc/testsuite/g++.dg/gomp/pr79664.C.jj      2017-02-22 16:29:07.715586641 
+0100
+++ gcc/testsuite/g++.dg/gomp/pr79664.C 2017-02-22 16:28:40.000000000 +0100
@@ -0,0 +1,168 @@
+// PR c++/79664
+// { dg-do compile }
+// { dg-options "-std=c++14 -fopenmp" }
+
+constexpr int
+f1 ()
+{
+  int i = 0;
+#pragma omp parallel for                       // { dg-error "is not a 
constant expression" }
+  for (i = 0; i < 10; ++i)
+    ;
+  return 0;
+}
+
+constexpr int
+f2 ()
+{
+  int i = 0;
+#pragma omp parallel                           // { dg-error "is not a 
constant expression" }
+  i = 5;
+  return 0;
+}
+
+constexpr int
+f3 ()
+{
+  int i = 0;
+#pragma omp task                               // { dg-error "is not a 
constant expression" }
+  i = 5;
+  return 0;
+}
+
+constexpr int
+f4 ()
+{
+  int i = 0;
+#pragma omp for                                        // { dg-error "is not a 
constant expression" }
+  for (i = 0; i < 10; ++i)
+    ;
+  return 0;
+}
+
+constexpr int
+f5 ()
+{
+  int i = 0;
+#pragma omp taskloop                           // { dg-error "is not a 
constant expression" }
+  for (i = 0; i < 10; ++i)
+    ;
+  return 0;
+}
+
+constexpr int
+f6 ()
+{
+  int i = 0;
+#pragma omp target teams                       // { dg-error "is not a 
constant expression" }
+  i = 5;
+  return 0;
+}
+
+constexpr int
+f7 ()
+{
+  int i = 0;
+#pragma omp target data map(tofrom:i)          // { dg-error "is not a 
constant expression" }
+  i = 5;
+  return 0;
+}
+
+constexpr int
+f8 ()
+{
+  int i = 0;
+#pragma omp target                             // { dg-error "is not a 
constant expression" }
+  i = 5;
+  return 0;
+}
+
+constexpr int
+f9 ()
+{
+  int i = 0;
+#pragma omp sections                           // { dg-error "is not a 
constant expression" }
+  {
+#pragma omp section
+    i = 5;
+  }
+  return 0;
+}
+
+constexpr int
+f10 ()
+{
+  int i = 0;
+#pragma omp ordered                            // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f11 ()
+{
+  int i = 0;
+#pragma omp critical                           // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f12 ()
+{
+  int i = 0;
+#pragma omp single                             // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f13 ()
+{
+  int i = 0;
+#pragma omp master                             // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f14 ()
+{
+  int i = 0;
+#pragma omp taskgroup                          // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f15 ()
+{
+  int i = 0;
+#pragma omp target update to(i)                        // { dg-error "is not a 
constant expression" }
+  i = 1;
+  return 0;
+}
+
+constexpr int
+f16 ()
+{
+  int i = 0;
+#pragma omp target update to(i)                        // { dg-error "is not a 
constant expression" }
+  return 0;
+}
+
+constexpr int
+f17 ()
+{
+  int i = 0;
+#pragma omp target enter data map(to:i)                // { dg-error "is not a 
constant expression" }
+  return 0;
+}
+
+constexpr int
+f18 ()
+{
+  int i = 0;
+#pragma omp target exit data map(from:i)       // { dg-error "is not a 
constant expression" }
+  return 0;
+}

        Jakub

Reply via email to