GCC Bugzilla – Attachment 26237 Details for
Bug 2316
g++ fails to overload on language linkage
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
remember linkage of a function type (5)
patch (text/plain), 34.09 KB, created by
Marc Glisse
on 2012-01-04 11:10:30 UTC
(
hide
)
Description:
remember linkage of a function type (5)
Filename:
MIME Type:
Creator:
Marc Glisse
Created:
2012-01-04 11:10:30 UTC
Size:
34.09 KB
patch
obsolete
>Index: libitm/alloc.cc >=================================================================== >--- libitm/alloc.cc (revision 182769) >+++ libitm/alloc.cc (working copy) >@@ -27,7 +27,7 @@ > namespace GTM HIDDEN { > > void >-gtm_thread::record_allocation (void *ptr, void (*free_fn)(void *)) >+gtm_thread::record_allocation (void *ptr, __freet free_fn) > { > uintptr_t iptr = (uintptr_t) ptr; > >@@ -40,7 +40,7 @@ > } > > void >-gtm_thread::forget_allocation (void *ptr, void (*free_fn)(void *)) >+gtm_thread::forget_allocation (void *ptr, __freet free_fn) > { > uintptr_t iptr = (uintptr_t) ptr; > >Index: libitm/beginend.cc >=================================================================== >--- libitm/beginend.cc (revision 182769) >+++ libitm/beginend.cc (working copy) >@@ -77,6 +77,7 @@ > free(tx); > } > >+extern "C" { > static void > thread_exit_handler(void *) > { >@@ -92,6 +93,7 @@ > if (pthread_key_create(&thr_release_key, thread_exit_handler)) > GTM_fatal("Creating thread release TLS key failed."); > } >+} > > > GTM::gtm_thread::~gtm_thread() >Index: libitm/libitm_i.h >=================================================================== >--- libitm/libitm_i.h (revision 182769) >+++ libitm/libitm_i.h (working copy) >@@ -33,7 +33,7 @@ > #include "config.h" > > #include <assert.h> >-#include <stdlib.h> >+#include <cstdlib> > #include <string.h> > #include <unwind.h> > #include "local_type_traits" >@@ -41,6 +41,7 @@ > > #include "common.h" > >+extern "C" typedef void(*__freet)(void*); > namespace GTM HIDDEN { > > using namespace std; >@@ -89,7 +90,7 @@ > // the template used inside gtm_thread can instantiate. > struct gtm_alloc_action > { >- void (*free_fn)(void *); >+ __freet free_fn; > bool allocated; > }; > >@@ -221,8 +222,8 @@ > > // In alloc.cc > void commit_allocations (bool, aa_tree<uintptr_t, gtm_alloc_action>*); >- void record_allocation (void *, void (*)(void *)); >- void forget_allocation (void *, void (*)(void *)); >+ void record_allocation (void *, __freet); >+ void forget_allocation (void *, __freet); > void drop_references_allocations (const void *ptr) > { > this->alloc_actions.erase((uintptr_t) ptr); >Index: libstdc++-v3/src/mt_allocator.cc >=================================================================== >--- libstdc++-v3/src/mt_allocator.cc (revision 182769) >+++ libstdc++-v3/src/mt_allocator.cc (working copy) >@@ -66,6 +66,7 @@ > return freelist_mutex; > } > >+ extern "C" { > static void > _M_destroy_thread_key(void* __id) > { >@@ -81,6 +82,7 @@ > freelist._M_thread_freelist = __tr; > } > } >+ } > #endif > } // anonymous namespace > >Index: libstdc++-v3/src/locale_init.cc >=================================================================== >--- libstdc++-v3/src/locale_init.cc (revision 182769) >+++ libstdc++-v3/src/locale_init.cc (working copy) >@@ -269,13 +269,13 @@ > _S_classic = new (&c_locale_impl) _Impl(2); > _S_global = _S_classic; > } >- >+extern "C" typedef void (*__initot)(); > void > locale::_S_initialize() > { > #ifdef __GTHREADS > if (__gthread_active_p()) >- __gthread_once(&_S_once, _S_initialize_once); >+ __gthread_once(&_S_once, (__initot)_S_initialize_once); > #endif > if (!_S_classic) > _S_initialize_once(); >Index: libstdc++-v3/include/std/type_traits >=================================================================== >--- libstdc++-v3/include/std/type_traits (revision 182769) >+++ libstdc++-v3/include/std/type_traits (working copy) >@@ -363,11 +363,21 @@ > { }; > > /// is_function >+ extern "C" template<class _Ret,class..._Args> using _CFun2=_Ret(_Args...); >+ extern "C" template<class _Ret,class..._Args> using _CFun3=_Ret(_Args......); > template<typename> > struct is_function > : public false_type { }; > > template<typename _Res, typename... _ArgTypes> >+ struct is_function<_CFun2<_Res,_ArgTypes...>> >+ : public true_type { }; >+ >+ template<typename _Res, typename... _ArgTypes> >+ struct is_function<_CFun3<_Res,_ArgTypes...>> >+ : public true_type { }; >+ >+ template<typename _Res, typename... _ArgTypes> > struct is_function<_Res(_ArgTypes...)> > : public true_type { }; > >@@ -375,6 +385,8 @@ > struct is_function<_Res(_ArgTypes......)> > : public true_type { }; > >+ /* const/volatile functions only make sense for member functions and thus >+ cannot be extern "C" */ > template<typename _Res, typename... _ArgTypes> > struct is_function<_Res(_ArgTypes...) const> > : public true_type { }; >Index: libstdc++-v3/include/std/functional >=================================================================== >--- libstdc++-v3/include/std/functional (revision 182769) >+++ libstdc++-v3/include/std/functional (working copy) >@@ -89,7 +89,17 @@ > { }; > > /// Retrieve the result type for a function type. >+ extern "C" template<class _Ret,class..._Args> using _CFun4=_Ret(_Args...); >+ extern "C" template<class _Ret,class..._Args> using _CFun5=_Ret(_Args......); > template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun4<_Res,_ArgTypes...>> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun5<_Res,_ArgTypes...>> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> > struct _Weak_result_type_impl<_Res(_ArgTypes...)> > { typedef _Res result_type; }; > >@@ -123,6 +133,14 @@ > > /// Retrieve the result type for a function reference. > template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun4<_Res,_ArgTypes...>&> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun5<_Res,_ArgTypes...>&> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> > struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)> > { typedef _Res result_type; }; > >@@ -132,6 +150,14 @@ > > /// Retrieve the result type for a function pointer. > template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun4<_Res,_ArgTypes...>*> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> >+ struct _Weak_result_type_impl<_CFun5<_Res,_ArgTypes...>*> >+ { typedef _Res result_type; }; >+ >+ template<typename _Res, typename... _ArgTypes> > struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)> > { typedef _Res result_type; }; > >Index: libstdc++-v3/include/ext/string_conversions.h >=================================================================== >--- libstdc++-v3/include/ext/string_conversions.h (revision 182769) >+++ libstdc++-v3/include/ext/string_conversions.h (working copy) >@@ -38,7 +38,7 @@ > #include <cwchar> > #include <cstdio> > #include <cerrno> >- >+extern "C" template<class Ret,class...Args> using _CFun=Ret(Args...); > namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) > { > _GLIBCXX_BEGIN_NAMESPACE_VERSION >@@ -47,7 +47,7 @@ > template<typename _TRet, typename _Ret = _TRet, typename _CharT, > typename... _Base> > _Ret >- __stoa(_TRet (*__convf) (const _CharT*, _CharT**, _Base...), >+ __stoa(_CFun<_TRet, const _CharT*, _CharT**, _Base...>*__convf, > const char* __name, const _CharT* __str, std::size_t* __idx, > _Base... __base) > { >@@ -76,8 +76,8 @@ > // Helper for the to_string / to_wstring functions. > template<typename _String, typename _CharT = typename _String::value_type> > _String >- __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*, >- __builtin_va_list), std::size_t __n, >+ __to_xstring(_CFun<int, _CharT*, std::size_t, const _CharT*, >+ __builtin_va_list>*__convf, std::size_t __n, > const _CharT* __fmt, ...) > { > // XXX Eventually the result will be constructed in place in >Index: libstdc++-v3/include/ext/codecvt_specializations.h >=================================================================== >--- libstdc++-v3/include/ext/codecvt_specializations.h (revision 182769) >+++ libstdc++-v3/include/ext/codecvt_specializations.h (working copy) >@@ -37,6 +37,8 @@ > #ifndef _EXT_CODECVT_SPECIALIZATIONS_H > #define _EXT_CODECVT_SPECIALIZATIONS_H 1 > >+#pragma GCC system_header >+ > #include <bits/c++config.h> > #include <locale> > #include <iconv.h> >@@ -218,7 +220,7 @@ > _GLIBCXX_END_NAMESPACE_VERSION > } // namespace > >- >+extern "C" template<class Ret,class...Args> using _CFun18=Ret(Args...); > namespace std _GLIBCXX_VISIBILITY(default) > { > _GLIBCXX_BEGIN_NAMESPACE_VERSION >@@ -297,7 +299,7 @@ > // Using this adaptor, g++ will do the work for us. > template<typename _Tp> > inline size_t >- __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), >+ __iconv_adaptor(_CFun18<size_t, iconv_t, _Tp, size_t*, char**, size_t*>*__func, > iconv_t __cd, char** __inbuf, size_t* __inbytes, > char** __outbuf, size_t* __outbytes) > { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } >Index: libstdc++-v3/include/ext/mt_allocator.h >=================================================================== >--- libstdc++-v3/include/ext/mt_allocator.h (revision 182769) >+++ libstdc++-v3/include/ext/mt_allocator.h (working copy) >@@ -35,7 +35,7 @@ > #include <bits/functexcept.h> > #include <ext/atomicity.h> > #include <bits/move.h> >- >+extern "C" typedef void (*__initt)(); > namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) > { > _GLIBCXX_BEGIN_NAMESPACE_VERSION >@@ -440,7 +440,7 @@ > { > // On some platforms, __gthread_once_t is an aggregate. > static __gthread_once_t __once = __GTHREAD_ONCE_INIT; >- __gthread_once(&__once, _S_initialize); >+ __gthread_once(&__once, (__initt)_S_initialize); > } > > // Double check initialization. May be necessary on some >@@ -535,7 +535,7 @@ > { > // On some platforms, __gthread_once_t is an aggregate. > static __gthread_once_t __once = __GTHREAD_ONCE_INIT; >- __gthread_once(&__once, _S_initialize); >+ __gthread_once(&__once, (__initt)_S_initialize); > } > > // Double check initialization. May be necessary on some >Index: libstdc++-v3/include/c_global/cstdlib >=================================================================== >--- libstdc++-v3/include/c_global/cstdlib (revision 182769) >+++ libstdc++-v3/include/c_global/cstdlib (working copy) >@@ -95,6 +95,25 @@ > #undef wcstombs > #undef wctomb > >+extern "C" typedef int (*c_cmp_fun_t)(const void*, const void*); >+ >+// libc could declare it with __asm("bsearch"), but it may not be safe to do >+// that here >+inline void * >+bsearch(const void *__key, const void *__base, size_t __nmemb, size_t __size, >+ int (*__compar)(const void *, const void *)) >+{ >+ return bsearch(__key, __base, __nmemb, __size, (c_cmp_fun_t)__compar); >+} >+ >+inline void >+qsort(void* __base, size_t __nmemb, size_t __size, >+ int (*__compar)(const void*, const void*)) >+{ >+ return qsort(__base, __nmemb, __size, (c_cmp_fun_t)__compar); >+} >+ >+ > namespace std _GLIBCXX_VISIBILITY(default) > { > _GLIBCXX_BEGIN_NAMESPACE_VERSION >Index: libstdc++-v3/include/tr1/type_traits >=================================================================== >--- libstdc++-v3/include/tr1/type_traits (revision 182769) >+++ libstdc++-v3/include/tr1/type_traits (working copy) >@@ -221,10 +221,21 @@ > { }; > > /// is_function >+ extern "C" template<class _Ret,class..._Args> using _CFun6=_Ret(_Args...); >+ extern "C" template<class _Ret,class..._Args> using _CFun7=_Ret(_Args......); >+ > template<typename> > struct is_function > : public false_type { }; >+/* See about that later > template<typename _Res, typename... _ArgTypes> >+ struct is_function<_CFun6<_Res,_ArgTypes...> > >+ : public true_type { }; >+ template<typename _Res, typename... _ArgTypes> >+ struct is_function<_CFun7<_Res,_ArgTypes...> > >+ : public true_type { }; >+*/ >+ template<typename _Res, typename... _ArgTypes> > struct is_function<_Res(_ArgTypes...)> > : public true_type { }; > template<typename _Res, typename... _ArgTypes> >Index: libstdc++-v3/libsupc++/unwind-cxx.h >=================================================================== >--- libstdc++-v3/libsupc++/unwind-cxx.h (revision 182769) >+++ libstdc++-v3/libsupc++/unwind-cxx.h (working copy) >@@ -51,7 +51,7 @@ > { > // Manage the exception object itself. > std::type_info *exceptionType; >- void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *); >+ __cxa_dtor_type exceptionDestructor; > > // The C++ standard has entertaining rules wrt calling set_terminate > // and set_unexpected in the middle of the exception cleanup process. >Index: libstdc++-v3/libsupc++/eh_throw.cc >=================================================================== >--- libstdc++-v3/libsupc++/eh_throw.cc (revision 182769) >+++ libstdc++-v3/libsupc++/eh_throw.cc (working copy) >@@ -29,6 +29,7 @@ > using namespace __cxxabiv1; > > >+extern "C" { > static void > __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) > { >@@ -55,11 +56,12 @@ > } > #endif > } >+} > > > extern "C" void > __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, >- void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) >+ __cxa_dtor_type dest) > { > // Definitely a primary. > __cxa_refcounted_exception *header >Index: libstdc++-v3/libsupc++/eh_ptr.cc >=================================================================== >--- libstdc++-v3/libsupc++/eh_ptr.cc (revision 182769) >+++ libstdc++-v3/libsupc++/eh_ptr.cc (working copy) >@@ -173,6 +173,7 @@ > } > > >+extern "C" { > static void > __gxx_dependent_exception_cleanup(_Unwind_Reason_Code code, > _Unwind_Exception *exc) >@@ -199,6 +200,7 @@ > __cxa_free_exception (header + 1); > } > } >+} > > > void >Index: libstdc++-v3/libsupc++/vec.cc >=================================================================== >--- libstdc++-v3/libsupc++/vec.cc (revision 182769) >+++ libstdc++-v3/libsupc++/vec.cc (working copy) >@@ -31,7 +31,10 @@ > #include <exception> > #include <bits/exception_defines.h> > #include "unwind-cxx.h" >- >+extern "C" typedef void* (*__mynewt)(std::size_t); >+extern "C" typedef void (*__mydelt)(void*); >+inline __mynewt castnewt(void*(*f)(std::size_t)){ return (__mynewt)f; } >+inline __mydelt castdelt(void (*f)(void*)){ return (__mydelt)f; } > namespace __cxxabiv1 > { > namespace >@@ -71,9 +74,12 @@ > { > return __cxa_vec_new2(element_count, element_size, padding_size, > constructor, destructor, >- &operator new[], &operator delete []); >+ castnewt(&operator new[]), >+ castdelt(&operator delete [])); > } > >+ /* Strangely enough, the cxx abi seems to imply that operator new[] has C >+ linkage (or there is an implicit cast going on). */ > extern "C" void * > __cxa_vec_new2(std::size_t element_count, > std::size_t element_size, >@@ -286,7 +292,7 @@ > { > __cxa_vec_delete2(array_address, element_size, padding_size, > destructor, >- &operator delete []); >+ castdelt(&operator delete [])); > } > > extern "C" void >Index: libstdc++-v3/libsupc++/cxxabi.h >=================================================================== >--- libstdc++-v3/libsupc++/cxxabi.h (revision 182769) >+++ libstdc++-v3/libsupc++/cxxabi.h (working copy) >@@ -63,7 +63,7 @@ > #endif > > typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *); >- >+ typedef void (_GLIBCXX_CDTOR_CALLABI *__cxa_dtor_type) (void *); > // Allocate array. > void* > __cxa_vec_new(size_t __element_count, size_t __element_size, >@@ -600,7 +600,7 @@ > > // Throw the exception. > void >- __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) >+ __cxa_throw(void*, std::type_info*, __cxa_dtor_type) > __attribute__((__noreturn__)); > > // Used to implement exception handlers. >Index: include/demangle.h >=================================================================== >--- include/demangle.h (revision 182769) >+++ include/demangle.h (working copy) >@@ -290,6 +290,9 @@ > /* The const qualifier. The one subtree is the type which is being > qualified. */ > DEMANGLE_COMPONENT_CONST, >+ /* extern "C" linkage. The one subtree is the function type which >+ is being qualified. */ >+ DEMANGLE_COMPONENT_EXTERN_C, > /* The restrict qualifier modifying a member function. The one > subtree is the type which is being qualified. */ > DEMANGLE_COMPONENT_RESTRICT_THIS, >Index: libiberty/cp-demangle.c >=================================================================== >--- libiberty/cp-demangle.c (revision 182769) >+++ libiberty/cp-demangle.c (working copy) >@@ -600,6 +600,9 @@ > case DEMANGLE_COMPONENT_CONST: > printf ("const\n"); > break; >+ case DEMANGLE_COMPONENT_EXTERN_C: >+ printf ("extern \"C\"\n"); >+ break; > case DEMANGLE_COMPONENT_RESTRICT_THIS: > printf ("restrict this\n"); > break; >@@ -817,6 +820,7 @@ > break; > > /* These types only require one parameter. */ >+ case DEMANGLE_COMPONENT_EXTERN_C: > case DEMANGLE_COMPONENT_VTABLE: > case DEMANGLE_COMPONENT_VTT: > case DEMANGLE_COMPONENT_TYPEINFO: >@@ -2401,18 +2405,22 @@ > d_function_type (struct d_info *di) > { > struct demangle_component *ret; >+ int is_extern_c = 0; > > if (! d_check_char (di, 'F')) > return NULL; > if (d_peek_char (di) == 'Y') > { >- /* Function has C linkage. We don't print this information. >- FIXME: We should print it in verbose mode. */ >+ /* Function has C linkage. */ >+ is_extern_c = 1; > d_advance (di, 1); >+ di->expansion += sizeof "extern \"C\""; > } > ret = d_bare_function_type (di, 1); > if (! d_check_char (di, 'E')) > return NULL; >+ if (is_extern_c) >+ ret = d_make_comp (di, DEMANGLE_COMPONENT_EXTERN_C, ret, NULL); > return ret; > } > >@@ -4041,6 +4049,7 @@ > case DEMANGLE_COMPONENT_RESTRICT_THIS: > case DEMANGLE_COMPONENT_VOLATILE_THIS: > case DEMANGLE_COMPONENT_CONST_THIS: >+ case DEMANGLE_COMPONENT_EXTERN_C: > case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: > case DEMANGLE_COMPONENT_POINTER: > case DEMANGLE_COMPONENT_COMPLEX: >@@ -4660,7 +4669,8 @@ > || (! suffix > && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS > || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS >- || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS))) >+ || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS >+ || mods->mod->type == DEMANGLE_COMPONENT_EXTERN_C))) > { > d_print_mod_list (dpi, options, mods->next, suffix); > return; >@@ -4751,6 +4761,9 @@ > case DEMANGLE_COMPONENT_CONST_THIS: > d_append_string (dpi, " const"); > return; >+ case DEMANGLE_COMPONENT_EXTERN_C: >+ d_append_string (dpi, " extern \"C\""); >+ return; > case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: > d_append_char (dpi, ' '); > d_print_comp (dpi, options, d_right (mod)); >@@ -4834,6 +4847,7 @@ > case DEMANGLE_COMPONENT_RESTRICT_THIS: > case DEMANGLE_COMPONENT_VOLATILE_THIS: > case DEMANGLE_COMPONENT_CONST_THIS: >+ case DEMANGLE_COMPONENT_EXTERN_C: > break; > default: > break; >Index: libgcc/gthr-posix.h >=================================================================== >--- libgcc/gthr-posix.h (revision 182769) >+++ libgcc/gthr-posix.h (working copy) >@@ -319,6 +319,10 @@ > # include <sched.h> > #endif > >+#ifdef __cplusplus >+extern "C" { >+#endif >+ > /* Key structure for maintaining thread specific storage */ > static pthread_key_t _objc_thread_storage; > static pthread_attr_t _objc_thread_attribs; >@@ -660,6 +664,10 @@ > > #else /* _LIBOBJC */ > >+#ifdef __cplusplus >+extern "C" { >+#endif >+ > static inline int > __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), > void *__args) >@@ -874,6 +882,10 @@ > return __gthrw_(pthread_cond_destroy) (__cond); > } > >+#ifdef __cplusplus >+} >+#endif >+ > #endif /* _LIBOBJC */ > > #endif /* ! GCC_GTHR_POSIX_H */ >Index: gcc/tree.c >=================================================================== >--- gcc/tree.c (revision 182769) >+++ gcc/tree.c (working copy) >@@ -7516,13 +7516,14 @@ > If such a type has already been constructed, reuse it. */ > > tree >-build_function_type (tree value_type, tree arg_types) >+build_function_type2 (tree value_type, tree arg_types, int extern_c) > { > tree t; > hashval_t hashcode = 0; > bool any_structural_p, any_noncanonical_p; > tree canon_argtypes; > >+ if (extern_c != 0) extern_c = 1; > if (TREE_CODE (value_type) == FUNCTION_TYPE) > { > error ("function return type cannot be function"); >@@ -7533,10 +7534,15 @@ > t = make_node (FUNCTION_TYPE); > TREE_TYPE (t) = value_type; > TYPE_ARG_TYPES (t) = arg_types; >+ if(extern_c) >+ { >+ TYPE_MINVAL (t) = integer_one_node; >+ } > > /* If we already have such a type, use the old one. */ > hashcode = iterative_hash_object (TYPE_HASH (value_type), hashcode); > hashcode = type_hash_list (arg_types, hashcode); >+ hashcode = iterative_hash_object (extern_c, hashcode); > t = type_hash_canon (hashcode, t); > > /* Set up the canonical type. */ >@@ -7548,13 +7554,18 @@ > if (any_structural_p) > SET_TYPE_STRUCTURAL_EQUALITY (t); > else if (any_noncanonical_p) >- TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type), >- canon_argtypes); >+ TYPE_CANONICAL (t) = build_function_type2 (TYPE_CANONICAL (value_type), >+ canon_argtypes, extern_c); > > if (!COMPLETE_TYPE_P (t)) > layout_type (t); > return t; > } >+tree >+build_function_type (tree value_type, tree arg_types) >+{ >+ return build_function_type2 (value_type, arg_types, 0); >+} > > /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. */ > >@@ -9694,7 +9705,7 @@ > else if (TREE_CODE (type) == FUNCTION_TYPE) > { > inner = reconstruct_complex_type (TREE_TYPE (type), bottom); >- outer = build_function_type (inner, TYPE_ARG_TYPES (type)); >+ outer = build_function_type2 (inner, TYPE_ARG_TYPES (type), TYPE_MINVAL(type)!=0); > } > else if (TREE_CODE (type) == METHOD_TYPE) > { >Index: gcc/tree.h >=================================================================== >--- gcc/tree.h (revision 182769) >+++ gcc/tree.h (working copy) >@@ -4385,6 +4385,7 @@ > extern tree build_nonshared_array_type (tree, tree); > extern tree build_array_type_nelts (tree, unsigned HOST_WIDE_INT); > extern tree build_function_type (tree, tree); >+extern tree build_function_type2 (tree, tree, int); > extern tree build_function_type_list (tree, ...); > extern tree build_function_type_skip_args (tree, bitmap); > extern tree build_function_decl_skip_args (tree, bitmap); >Index: gcc/cp/typeck.c >=================================================================== >--- gcc/cp/typeck.c (revision 182769) >+++ gcc/cp/typeck.c (working copy) >@@ -506,6 +506,12 @@ > types. */ > if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2)) > result_type = pointee1; >+ else if (comptypes (TYPE_MAIN_VARIANT (pointee1), TYPE_MAIN_VARIANT (pointee2), COMPARE_IGNOREEXTC)) >+ { >+ result_type = pointee1; >+ if (complain & tf_warning) >+ warning_at (input_location, OPT_Wall, "invalid composition of %qT and %qT", t1, t2); >+ } > else if ((TREE_CODE (pointee1) == POINTER_TYPE > && TREE_CODE (pointee2) == POINTER_TYPE) > || (TYPE_PTR_TO_MEMBER_P (pointee1) >@@ -830,7 +836,7 @@ > else > parms = commonparms (p1, p2); > >- rval = build_function_type (valtype, parms); >+ rval = build_function_type2 (valtype, parms, TYPE_MINVAL (t1) != 0); > gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2)); > rval = apply_memfn_quals (rval, type_memfn_quals (t1)); > raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), >@@ -1275,16 +1281,18 @@ > case POINTER_TYPE: > if (TYPE_MODE (t1) != TYPE_MODE (t2) > || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2) >- || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) >+ || !comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict & COMPARE_IGNOREEXTC)) > return false; > break; > > case METHOD_TYPE: > case FUNCTION_TYPE: >- if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) >+ if (!comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict & COMPARE_IGNOREEXTC)) > return false; >- if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))) >+ if (!compparms2 (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict & COMPARE_IGNOREEXTC)) > return false; >+ if (!(strict & COMPARE_IGNOREEXTC) && (TYPE_MINVAL (t1) != TYPE_MINVAL (t2))) >+ return false; > break; > > case ARRAY_TYPE: >@@ -1385,12 +1393,14 @@ > bool result = structural_comptypes (t1, t2, strict); > > if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2)) >+ { > /* The two types are structurally equivalent, but their > canonical types were different. This is a failure of the > canonical type propagation code.*/ > internal_error > ("canonical types differ for identical types %T and %T", > t1, t2); >+ } > else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)) > /* Two types are structurally different, but the canonical > types are the same. This means we were over-eager in >@@ -1481,7 +1491,7 @@ > element by element. */ > > bool >-compparms (const_tree parms1, const_tree parms2) >+compparms2 (const_tree parms1, const_tree parms2, int strict) > { > const_tree t1, t2; > >@@ -1496,11 +1506,16 @@ > they fail to match. */ > if (!t1 || !t2) > return false; >- if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2))) >+ if (!comptypes (TREE_VALUE (t1), TREE_VALUE (t2), strict)) > return false; > } > return true; > } >+bool >+compparms (const_tree parms1, const_tree parms2) >+{ >+ return compparms2 (parms1, parms2, COMPARE_STRICT); >+} > > > /* Process a sizeof or alignof expression where the operand is a >Index: gcc/cp/class.c >=================================================================== >--- gcc/cp/class.c (revision 182769) >+++ gcc/cp/class.c (working copy) >@@ -6766,6 +6766,8 @@ > are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy > interoperability with most_specialized_instantiation. */ > tree matches = NULL_TREE; >+ tree matches2 = NULL_TREE; >+ bool hasmatch2 = 0; > tree fn; > tree target_fn_type; > >@@ -6835,12 +6837,16 @@ > /* See if there's a match. */ > if (same_type_p (target_fn_type, static_fn_type (fn))) > matches = tree_cons (fn, NULL_TREE, matches); >+ /* See if there's a match. */ >+ if (comptypes (target_fn_type, static_fn_type (fn), COMPARE_IGNOREEXTC)) >+ matches2 = tree_cons (fn, NULL_TREE, matches2); > } > } > > /* Now, if we've already got a match (or matches), there's no need > to proceed to the template functions. But, if we don't have a > match we need to look at them, too. */ >+ hasmatch2 = !matches2; > if (!matches) > { > tree target_arg_types; >@@ -6894,6 +6900,9 @@ > /* See if there's a match. */ > if (same_type_p (target_fn_type, static_fn_type (instantiation))) > matches = tree_cons (instantiation, fn, matches); >+ /* See if there's a match. */ >+ if (!hasmatch2 && comptypes (target_fn_type, static_fn_type (instantiation), COMPARE_IGNOREEXTC)) >+ matches2 = tree_cons (instantiation, fn, matches2); > } > > /* Now, remove all but the most specialized of the matches. */ >@@ -6909,6 +6918,7 @@ > } > > /* Now we should have exactly one function in MATCHES. */ >+ if (matches == NULL_TREE) matches = matches2; > if (matches == NULL_TREE) > { > /* There were *no* matches. */ >Index: gcc/cp/decl.c >=================================================================== >--- gcc/cp/decl.c (revision 182769) >+++ gcc/cp/decl.c (working copy) >@@ -9290,7 +9290,7 @@ > parms = NULL_TREE; > } > >- type = build_function_type (type, arg_types); >+ type = build_function_type2 (type, arg_types, current_lang_name == lang_name_c); > } > break; > >Index: gcc/cp/error.c >=================================================================== >--- gcc/cp/error.c (revision 182769) >+++ gcc/cp/error.c (working copy) >@@ -834,6 +834,8 @@ > pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (t)); > else > pp_cxx_cv_qualifier_seq (cxx_pp, t); >+ if (TREE_CODE (t) == FUNCTION_TYPE && TYPE_MINVAL (t)) >+ pp_string (cxx_pp, " extern \"C\""); > dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags); > dump_type_suffix (TREE_TYPE (t), flags); > break; >Index: gcc/cp/tree.c >=================================================================== >--- gcc/cp/tree.c (revision 182769) >+++ gcc/cp/tree.c (working copy) >@@ -1154,8 +1154,8 @@ > } > else > { >- result = build_function_type (type, >- arg_types); >+ result = build_function_type2 (type, arg_types, >+ TYPE_MINVAL (t) != 0); > result = apply_memfn_quals (result, type_memfn_quals (t)); > } > >Index: gcc/cp/pt.c >=================================================================== >--- gcc/cp/pt.c (revision 182769) >+++ gcc/cp/pt.c (working copy) >@@ -10947,7 +10947,7 @@ > /* Construct a new type node and return it. */ > if (TREE_CODE (t) == FUNCTION_TYPE) > { >- fntype = build_function_type (return_type, arg_types); >+ fntype = build_function_type2 (return_type, arg_types, TYPE_MINVAL (t)!=0); > fntype = apply_memfn_quals (fntype, type_memfn_quals (t)); > } > else >Index: gcc/cp/decl2.c >=================================================================== >--- gcc/cp/decl2.c (revision 182769) >+++ gcc/cp/decl2.c (working copy) >@@ -157,7 +157,7 @@ > > if (TREE_CODE (fntype) == FUNCTION_TYPE) > { >- newtype = build_function_type (new_ret, args); >+ newtype = build_function_type2 (new_ret, args, TYPE_MINVAL (fntype) != 0); > newtype = apply_memfn_quals (newtype, type_memfn_quals (fntype)); > } > else >@@ -1252,7 +1252,7 @@ > else if (TREE_CODE (type) == FUNCTION_TYPE) > { > inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); >- outer = build_function_type (inner, TYPE_ARG_TYPES (type)); >+ outer = build_function_type2 (inner, TYPE_ARG_TYPES (type), TYPE_MINVAL (type) != 0); > outer = apply_memfn_quals (outer, type_memfn_quals (type)); > } > else if (TREE_CODE (type) == METHOD_TYPE) >Index: gcc/cp/parser.c >=================================================================== >--- gcc/cp/parser.c (revision 182769) >+++ gcc/cp/parser.c (working copy) >@@ -13754,7 +13754,7 @@ > /* If it's not a class-name, keep looking. */ > if (!cp_parser_parse_definitely (parser)) > { >- if (cxx_dialect < cxx0x) >+ if ((cxx_dialect < cxx0x) && !in_system_header) > /* It must be a typedef-name or an enum-name. */ > return cp_parser_nonclass_name (parser); > >@@ -21179,6 +21179,7 @@ > VEC (deferred_access_check,gc) *checks; > tree parameter_list; > bool friend_p = false; >+ location_t loc_c_linkage_error; > bool need_lang_pop; > cp_token *token; > >@@ -21205,7 +21206,7 @@ > A template ... shall not have C linkage. */ > if (current_lang_name == lang_name_c) > { >- error_at (token->location, "template with C linkage"); >+ loc_c_linkage_error = token->location; > /* Give it C++ linkage to avoid confusing other parts of the > front end. */ > push_lang_context (lang_name_cplusplus); >@@ -21250,9 +21251,18 @@ > if (cp_lexer_next_token_is_keyword (parser->lexer, > RID_TEMPLATE)) > cp_parser_template_declaration_after_export (parser, member_p); >- else if (cxx_dialect >= cxx0x >+ else if ((cxx_dialect >= cxx0x || in_system_header) > && cp_lexer_next_token_is_keyword (parser->lexer, RID_USING)) >- decl = cp_parser_alias_declaration (parser); >+ { >+ /* For a template alias, C linkage should be OK, although it is possible >+ that the standard officially forbids it currently */ >+ if (need_lang_pop) >+ { >+ need_lang_pop = false; >+ pop_lang_context (); >+ } >+ decl = cp_parser_alias_declaration (parser); >+ } > else > { > /* There are no access checks when parsing a template, as we do not >@@ -21320,7 +21330,10 @@ > /* For the erroneous case of a template with C linkage, we pushed an > implicit C++ linkage scope; exit that scope now. */ > if (need_lang_pop) >- pop_lang_context (); >+ { >+ error_at (loc_c_linkage_error, "template with C linkage"); >+ pop_lang_context (); >+ } > /* If DECL is a function template, we must return to parse it later. > (Even though there is no definition, there might be default > arguments that need handling.) */ >Index: gcc/cp/call.c >=================================================================== >--- gcc/cp/call.c (revision 182769) >+++ gcc/cp/call.c (working copy) >@@ -71,6 +71,7 @@ > cr_pbool, > cr_user, > cr_ellipsis, >+ cr_extc, > cr_bad > } conversion_rank; > >@@ -1256,6 +1257,12 @@ > else if (c_dialect_objc () > && objc_compare_types (to, from, -4, NULL_TREE)) > conv = build_conv (ck_ptr, to, conv); >+ else if (comptypes (from, to, COMPARE_IGNOREEXTC)) >+ { >+ conv = build_conv (ck_ptr, to, conv); >+ if (conv->rank < cr_extc) >+ conv->rank = cr_extc; >+ } > else if (ptr_reasonably_similar (to_pointee, from_pointee)) > { > conv = build_conv (ck_ptr, to, conv); >@@ -5671,6 +5678,15 @@ > if (issue_conversion_warnings && (complain & tf_warning)) > conversion_null_warnings (totype, expr, fn, argnum); > >+ if (issue_conversion_warnings && (complain & tf_warning) && convs->rank == cr_extc) >+ { >+ warning_at (input_location, OPT_Wall, "invalid conversion from %qT to %qT", >+ TREE_TYPE (expr), totype); >+ if (fn) >+ warning_at (DECL_SOURCE_LOCATION (fn), OPT_Wall, >+ " initializing argument %P of %qD", argnum, fn); >+ } >+ > switch (convs->kind) > { > case ck_user: >Index: gcc/cp/mangle.c >=================================================================== >--- gcc/cp/mangle.c (revision 182769) >+++ gcc/cp/mangle.c (working copy) >@@ -2285,6 +2285,8 @@ > } > > write_char ('F'); >+ if(TYPE_MINVAL (type)) >+ write_char ('Y'); > /* We don't track whether or not a type is `extern "C"'. Note that > you can have an `extern "C"' function that does not have > `extern "C"' type, and vice versa: >Index: gcc/cp/cp-tree.h >=================================================================== >--- gcc/cp/cp-tree.h (revision 182769) >+++ gcc/cp/cp-tree.h (working copy) >@@ -4471,6 +4471,8 @@ > structural. The actual comparison > will be identical to > COMPARE_STRICT. */ >+#define COMPARE_IGNOREEXTC 16 /* The comparison should ignore >+ extern "C" on function types. */ > > /* Used with push_overloaded_decl. */ > #define PUSH_GLOBAL 0 /* Push the DECL into namespace scope, >@@ -5755,6 +5757,7 @@ > extern bool comptypes (tree, tree, int); > extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree); > extern bool compparms (const_tree, const_tree); >+extern bool compparms2 (const_tree, const_tree, int); > extern int comp_cv_qualification (const_tree, const_tree); > extern int comp_cv_qual_signature (tree, tree); > extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2316
:
25134
|
25140
|
25181
|
26214
| 26237