re PR c++/79664 (ICE with #pragma omp parallel in constexpr function)
authorJakub Jelinek <jakub@redhat.com>
Wed, 22 Feb 2017 22:36:20 +0000 (23:36 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 22 Feb 2017 22:36:20 +0000 (23:36 +0100)
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
EXPR_LOC_OR_LOC (t, input_location) computed early
instead of error, or error_at with location_of (t).

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

From-SVN: r245662

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C
gcc/testsuite/g++.dg/gomp/pr79664.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/teams-1.C

index c036f8cf0e066bee23965dc61181fab087dfdd76..e69e2eafdf1d3baf6d5cbbd8d9135ed28e468ecd 100644 (file)
@@ -1,3 +1,13 @@
+2017-02-22  Jakub Jelinek  <jakub@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
+       EXPR_LOC_OR_LOC (t, input_location) computed early
+       instead of error, or error_at with location_of (t).
+
 2017-02-22  Marek Polacek  <polacek@redhat.com>
 
        PR c++/79653
index 3fe501a8a276115ed7801607951de52d09ac0dc4..81489570d282947e6ae97110c0a016b740fb7e95 100644 (file)
@@ -5001,10 +5001,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     return false;
   if (t == NULL_TREE)
     return true;
+  location_t loc = EXPR_LOC_OR_LOC (t, input_location);
   if (TREE_THIS_VOLATILE (t) && !DECL_P (t))
     {
       if (flags & tf_error)
-        error ("expression %qE has side-effects", t);
+        error_at (loc, "expression %qE has side-effects", t);
       return false;
     }
   if (CONSTANT_CLASS_P (t))
@@ -5086,8 +5087,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
              {
                /* fold_call_expr can't do anything with IFN calls.  */
                if (flags & tf_error)
-                 error_at (EXPR_LOC_OR_LOC (t, input_location),
-                           "call to internal function %qE", t);
+                 error_at (loc, "call to internal function %qE", t);
                return false;
              }
          }
@@ -5105,8 +5105,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
                  {
                    if (flags & tf_error)
                      {
-                       error_at (EXPR_LOC_OR_LOC (t, input_location),
-                                 "call to non-constexpr function %qD", fun);
+                       error_at (loc, "call to non-constexpr function %qD",
+                                 fun);
                        explain_invalid_constexpr_fn (fun);
                      }
                    return false;
@@ -5199,8 +5199,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
            && !integer_zerop (from))
          {
            if (flags & tf_error)
-             error_at (EXPR_LOC_OR_LOC (t, input_location),
-                       "reinterpret_cast from integer to pointer");
+             error_at (loc, "reinterpret_cast from integer to pointer");
            return false;
          }
         return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
@@ -5266,7 +5265,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
                && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x)))
              {
                if (flags & tf_error)
-                 error ("use of %<this%> in a constant expression");
+                 error_at (loc, "use of %<this%> in a constant expression");
                return false;
              }
            return true;
@@ -5354,10 +5353,40 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     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 +5395,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case AT_ENCODE_EXPR:
     fail:
       if (flags & tf_error)
-       error ("expression %qE is not a constant expression", t);
+       error_at (loc, "expression %qE is not a constant expression", t);
       return false;
 
     case TYPEID_EXPR:
@@ -5378,8 +5407,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
            && 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 (loc, "typeid-expression is not a constant expression "
+                       "because %qE is of polymorphic type", e);
             return false;
           }
         return true;
@@ -5438,8 +5467,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
           constant expression.  */
        {
          if (flags & tf_error)
-           error ("cast to non-integral type %qT in a constant expression",
-                  TREE_TYPE (t));
+           error_at (loc,
+                     "cast to non-integral type %qT in a constant expression",
+                     TREE_TYPE (t));
          return false;
        }
 
@@ -5504,8 +5534,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
        {
          if (flags & tf_error)
            {
-             error ("temporary of non-literal type %qT in a "
-                    "constant expression", TREE_TYPE (t));
+             error_at (loc, "temporary of non-literal type %qT in a "
+                       "constant expression", TREE_TYPE (t));
              explain_non_literal_class (TREE_TYPE (t));
            }
          return false;
@@ -5657,8 +5687,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
       if (COND_EXPR_IS_VEC_DELETE (t))
        {
          if (flags & tf_error)
-           error_at (location_of (t),
-                     "%<delete[]%> is not a constant expression");
+           error_at (loc, "%<delete[]%> is not a constant expression");
          return false;
        }
       /* Fall through.  */
@@ -5681,7 +5710,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
                                             want_rval, strict, tf_none))
          return true;
       if (flags & tf_error)
-       error ("expression %qE is not a constant expression", t);
+       error_at (loc, "expression %qE is not a constant expression", t);
       return false;
 
     case VEC_INIT_EXPR:
@@ -5689,7 +5718,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
        return true;
       if (flags & tf_error)
        {
-         error ("non-constant array initialization");
+         error_at (loc, "non-constant array initialization");
          diagnose_non_constexpr_vec_init (t);
        }
       return false;
@@ -5710,7 +5739,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
        if (breaks (target) || continues (target))
          return true;
        if (flags & tf_error)
-         error ("%<goto%> is not a constant expression");
+         error_at (loc, "%<goto%> is not a constant expression");
        return false;
       }
 
index e20257c5bf9888f1b68515c6fb1ca916880d8ea4..ffc0e88742a4fa94131def1573989db5ce2e10dc 100644 (file)
@@ -35526,6 +35526,7 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
          OMP_TEAMS_CLAUSES (ret) = clauses;
          OMP_TEAMS_BODY (ret) = body;
          OMP_TEAMS_COMBINED (ret) = 1;
+         SET_EXPR_LOCATION (ret, loc);
          return add_stmt (ret);
        }
     }
@@ -35547,6 +35548,7 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
   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);
 }
@@ -35965,6 +35967,7 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
          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;
index c5f757635d2aa1761677fbbef0aaefc52bffb62e..9279d5842dbf6ac06e0215551957303d05e7422e 100644 (file)
@@ -1,5 +1,10 @@
 2017-02-22  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/79664
+       * g++.dg/gomp/teams-1.C: Adjust expected diagnostic location.
+       * g++.dg/cpp1y/constexpr-throw.C: Likewise.
+       * g++.dg/gomp/pr79664.C: New test.
+
        * g++.dg/debug/dwarf2/inline-var-2.C: New test.
 
 2017-02-22  Marek Polacek  <polacek@redhat.com>
index eed07205efb0dc63f707868ea18d12df48f38ab2..21629a7990abd90bf7df28d894f67e029dbf9cde 100644 (file)
@@ -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) {
diff --git a/gcc/testsuite/g++.dg/gomp/pr79664.C b/gcc/testsuite/g++.dg/gomp/pr79664.C
new file mode 100644 (file)
index 0000000..582eedb
--- /dev/null
@@ -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;
+}
index d0460c3c22c3ffa91b7af0a3c6f6650dde9e4116..3cea407bf1bf6d68693524f6a39b101721389b19 100644 (file)
@@ -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 }
   }
 }