Hi,

in the language of our implementations details, submitter noticed that in terms of warnings we handle in a different way COND_EXPRs in tsubst_copy_and_build - we use fold_non_dependent_expr and integer_zerop to suppress undesired warnings by bumping c_inhibit_evaluation_warnings - and IF_STMTs in tsubst_expr, where we don't. My patch below, which passes testing, tries in a rather straightforward way to adopt the same mechanisms in the latter. There are quite a few details I'm not sure about: whether we should only use fold_non_dependent_expr for the purpose of suppressing the warnings - thus never touching 'tmp' in the pt.c code handling IF_STMTs - which would be completely conservative in terms of code generation; whether there are subtle interactions with the new if constexpr, which I'm missing at the moment.


Thanks!

Paolo.

//////////////////

Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 241297)
+++ cp/pt.c     (working copy)
@@ -15403,26 +15403,46 @@
       break;
 
     case IF_STMT:
-      stmt = begin_if_stmt ();
-      IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t);
-      tmp = RECUR (IF_COND (t));
-      tmp = finish_if_stmt_cond (tmp, stmt);
-      if (IF_STMT_CONSTEXPR_P (t) && integer_zerop (tmp))
-       /* Don't instantiate the THEN_CLAUSE. */;
-      else
-       RECUR (THEN_CLAUSE (t));
-      finish_then_clause (stmt);
+      {
+       tree folded_tmp;
+       bool zerop, nonzerop;
 
-      if (IF_STMT_CONSTEXPR_P (t) && integer_nonzerop (tmp))
-       /* Don't instantiate the ELSE_CLAUSE. */;
-      else if (ELSE_CLAUSE (t))
-       {
-         begin_else_clause (stmt);
-         RECUR (ELSE_CLAUSE (t));
-         finish_else_clause (stmt);
-       }
+       stmt = begin_if_stmt ();
+       IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t);
+       tmp = RECUR (IF_COND (t));
+       folded_tmp = fold_non_dependent_expr (tmp);
+       if (TREE_CODE (folded_tmp) == INTEGER_CST)
+         tmp = folded_tmp;
+       tmp = finish_if_stmt_cond (tmp, stmt);
+       zerop = integer_zerop (tmp);
+       nonzerop = integer_nonzerop (tmp);
+       if (IF_STMT_CONSTEXPR_P (t) && zerop)
+         /* Don't instantiate the THEN_CLAUSE. */;
+       else
+         {
+           if (zerop)
+             ++c_inhibit_evaluation_warnings;
+           RECUR (THEN_CLAUSE (t));
+           if (zerop)
+             --c_inhibit_evaluation_warnings;
+         }
+       finish_then_clause (stmt);
 
-      finish_if_stmt (stmt);
+       if (IF_STMT_CONSTEXPR_P (t) && nonzerop)
+         /* Don't instantiate the ELSE_CLAUSE. */;
+       else if (ELSE_CLAUSE (t))
+         {
+           begin_else_clause (stmt);
+           if (nonzerop)
+             ++c_inhibit_evaluation_warnings;
+           RECUR (ELSE_CLAUSE (t));
+           if (nonzerop)
+             --c_inhibit_evaluation_warnings;
+           finish_else_clause (stmt);
+         }
+
+       finish_if_stmt (stmt);
+      }
       break;
 
     case BIND_EXPR:
Index: testsuite/g++.dg/cpp1y/pr67980.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr67980.C    (revision 0)
+++ testsuite/g++.dg/cpp1y/pr67980.C    (working copy)
@@ -0,0 +1,23 @@
+// { dg-do compile { target c++14 } }
+
+template <int Y, class T>
+constexpr T cpp14_constexpr_then(T value) {
+  if (Y < 0)
+    return (value << -Y);
+  else
+    return 0;
+}
+
+template <int Y, class T>
+constexpr T cpp14_constexpr_else(T value) {
+  if (Y > 0)
+    return 0;
+  else
+    return (value << -Y);
+}
+
+int main()
+{
+  cpp14_constexpr_then<1>(0);
+  cpp14_constexpr_else<1>(0);
+}

Reply via email to