[pushed] c++: Fix stdcall attribute in template. [PR95222]

Message ID 20200527140946.17617-1-jason@redhat.com
State New
Headers show
Series
  • [pushed] c++: Fix stdcall attribute in template. [PR95222]
Related show

Commit Message

Kewen.Lin via Gcc-patches May 27, 2020, 2:09 p.m.
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.

Tested x86_64-pc-linux-gnu, applying to trunk.

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                         |  2 +-
 gcc/testsuite/g++.dg/ext/tmplattr10.C | 52 +++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/tmplattr10.C


base-commit: ac9face8d26ea4b6aa72902ecc22e89ef00763c5
-- 
2.18.1

Patch

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2e1390837e8..5476965996b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
index 00000000000..3fb8c21ccbe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/tmplattr10.C
@@ -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);
+}