Patchwork PR c++/47326

login
register
mail settings
Submitter Dodji Seketeli
Date Feb. 16, 2011, 4:28 p.m.
Message ID <m339nogd0b.fsf@redhat.com>
Download mbox | patch
Permalink /patch/83375/
State New
Headers show

Comments

Dodji Seketeli - Feb. 16, 2011, 4:28 p.m.
Hello,

Consider this example:

    template <int _N>
    struct A
    {
      typedef int value_type;
    };

    template <typename... _ARGS>
    auto
    f (_ARGS... args) -> typename A<sizeof...(args)>::value_type
    {
      return 12;
    }

    int
    main()
    {
      f(1,2);
    }

Near the end of unification of f(1,2), we substitute the unified types
into the return type of f and we fail to ensure that the argument
[when it is a pack expansion] of sizeof is not evaluated.

Tested on x86_64-unknown-linux-gnu against trunk.
Jason Merrill - Feb. 16, 2011, 4:31 p.m.
OK.

Jason

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d59f32a..64eb027 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11380,11 +11380,18 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case SIZEOF_EXPR:
       if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
         {
-          /* We only want to compute the number of arguments.  */
-          tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
-                                                complain, in_decl);
+
+          tree expanded;
 	  int len = 0;
 
+	  ++cp_unevaluated_operand;
+	  ++c_inhibit_evaluation_warnings;
+	  /* We only want to compute the number of arguments.  */
+	  expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
+					    complain, in_decl);
+	  --cp_unevaluated_operand;
+	  --c_inhibit_evaluation_warnings;
+
 	  if (TREE_CODE (expanded) == TREE_VEC)
 	    len = TREE_VEC_LENGTH (expanded);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic106.C b/gcc/testsuite/g++.dg/cpp0x/variadic106.C
new file mode 100644
index 0000000..80ec084
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic106.C
@@ -0,0 +1,22 @@ 
+// Origin: PR c++/47326
+// { dg-options  "-std=c++0x" }
+// { dg-do compile }
+
+template <int _N>
+struct A
+{
+  typedef int value_type;
+};
+
+template <typename... _ARGS>
+auto
+f (_ARGS... args) -> typename A<sizeof...(args)>::value_type
+{
+  return 12;
+}
+
+int
+main()
+{
+  f(1,2);
+}