aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-25 19:04:05 -0400
committerJason Merrill <jason@redhat.com>2020-05-27 10:05:36 -0400
commit7e7d9fcff56385812764cba63e1ebf6f4c6c0320 (patch)
tree03fd6be5b8acba5828f235a00df7b3cfb782f688 /gcc
parentac9face8d26ea4b6aa72902ecc22e89ef00763c5 (diff)
downloadgcc-7e7d9fcff56385812764cba63e1ebf6f4c6c0320.zip
gcc-7e7d9fcff56385812764cba63e1ebf6f4c6c0320.tar.gz
gcc-7e7d9fcff56385812764cba63e1ebf6f4c6c0320.tar.bz2
c++: Fix stdcall attribute in template. [PR95222]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/testsuite/g++.dg/ext/tmplattr10.C52
2 files changed, 53 insertions, 1 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2e13908..5476965 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 0000000..3fb8c21
--- /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);
+}