c++: Fix stdcall attribute in template. [PR95222]
authorJason Merrill <jason@redhat.com>
Mon, 25 May 2020 23:04:05 +0000 (19:04 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 27 May 2020 14:05:36 +0000 (10:05 -0400)
Another case that breaks with my fix for PR90750: we shouldn't move type
attributes in TYPENAME context either, as there's no decl for them to move
to.

gcc/cp/ChangeLog:

PR c++/95222
* decl.c (grokdeclarator): Don't shift attributes in TYPENAME
context.

gcc/testsuite/ChangeLog:

PR c++/95222
* g++.dg/ext/tmplattr10.C: New test.

gcc/cp/decl.c
gcc/testsuite/g++.dg/ext/tmplattr10.C [new file with mode: 0644]

index 2e1390837e86c94dafaa066c466d5aa8a23fc2b6..5476965996b1f58781225a570394f90b6f3acb99 100644 (file)
@@ -11951,7 +11951,7 @@ grokdeclarator (const cp_declarator *declarator,
          if (declarator->kind == cdk_array)
            attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
          tree late_attrs = NULL_TREE;
-         if (decl_context != PARM)
+         if (decl_context != PARM && decl_context != TYPENAME)
            /* Assume that any attributes that get applied late to
               templates will DTRT when applied to the declaration
               as a whole.  */
diff --git a/gcc/testsuite/g++.dg/ext/tmplattr10.C b/gcc/testsuite/g++.dg/ext/tmplattr10.C
new file mode 100644 (file)
index 0000000..3fb8c21
--- /dev/null
@@ -0,0 +1,52 @@
+// PR c++/95222
+// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+
+#if defined(_MSC_VER)
+#define CC_FASTCALL __fastcall
+#define CC_STDCALL __stdcall
+#else
+#define CC_FASTCALL __attribute__((fastcall))
+#define CC_STDCALL __attribute__((stdcall))
+#endif
+
+template <typename FuncT>
+struct FuncResult;
+
+template <typename R, typename... Args>
+struct FuncResult<R(*)(Args...)>
+{
+    using type = R;
+};
+
+template <typename R, typename... Args>
+struct FuncResult<R(CC_FASTCALL*)(Args...)>
+{
+    using type = R;
+};
+
+template <typename R, typename... Args>
+struct FuncResult<R(CC_STDCALL*)(Args...)>
+{
+    using type = R;
+};
+
+template <typename FuncT>
+auto wrap(FuncT f) -> typename FuncResult<FuncT>::type
+{
+    return f(1, 2, 3);
+}
+
+int CC_FASTCALL func1(int x, int y, int z)
+{
+    return x + y + z;
+}
+
+int CC_STDCALL func2(int x, int y, int z)
+{
+    return x + y + z;
+}
+
+int main()
+{
+    return wrap(&func1) + wrap(&func2);
+}