Index: libstdc++-v3/include/ext/string_conversions.h =================================================================== --- libstdc++-v3/include/ext/string_conversions.h (revision 178336) +++ libstdc++-v3/include/ext/string_conversions.h (working copy) @@ -44,10 +44,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Helper for all the sto* functions. - template _Ret - __stoa(_TRet (*__convf) (const _CharT*, _CharT**, _Base...), + __stoa(_F __convf, const char* __name, const _CharT* __str, std::size_t* __idx, _Base... __base) { @@ -55,7 +55,7 @@ _CharT* __endptr; errno = 0; - const _TRet __tmp = __convf(__str, &__endptr, __base...); + const auto __tmp = __convf(__str, &__endptr, __base...); if (__endptr == __str) std::__throw_invalid_argument(__name); @@ -74,10 +74,9 @@ } // Helper for the to_string / to_wstring functions. - template + template _String - __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*, - __builtin_va_list), std::size_t __n, + __to_xstring(_F __convf, std::size_t __n, const _CharT* __fmt, ...) { // XXX Eventually the result will be constructed in place in Index: libstdc++-v3/include/bits/basic_string.h =================================================================== --- libstdc++-v3/include/bits/basic_string.h (revision 178336) +++ libstdc++-v3/include/bits/basic_string.h (working copy) @@ -2807,41 +2807,41 @@ // 21.4 Numeric Conversions [string.conversions]. inline int stoi(const string& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::strtol, "stoi", __str.c_str(), + { return __gnu_cxx::__stoa(&std::strtol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const string& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(), + { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const string& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(), + { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const string& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(), + { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(), + { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(), __idx, __base); } // NB: strtof vs strtod. inline float stof(const string& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); } inline double stod(const string& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); } inline long double stold(const string& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); } // NB: (v)snprintf vs sprintf. @@ -2910,41 +2910,41 @@ #ifdef _GLIBCXX_USE_WCHAR_T inline int stoi(const wstring& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::wcstol, "stoi", __str.c_str(), + { return __gnu_cxx::__stoa(&std::wcstol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const wstring& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(), + { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const wstring& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(), + { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const wstring& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(), + { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10) - { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(), + { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(), __idx, __base); } // NB: wcstof vs wcstod. inline float stof(const wstring& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); } inline double stod(const wstring& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); } inline long double stold(const wstring& __str, size_t* __idx = 0) - { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); } + { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); } // DR 1261. inline wstring Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 178336) +++ gcc/tree.c (working copy) @@ -7521,7 +7521,7 @@ 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; @@ -7538,10 +7538,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. */ @@ -7553,13 +7558,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. */ Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 178336) +++ gcc/tree.h (working copy) @@ -4337,6 +4337,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 178336) +++ gcc/cp/typeck.c (working copy) @@ -1281,6 +1281,8 @@ return false; if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))) return false; + if (TYPE_MINVAL (t1) != TYPE_MINVAL (t2)) + return false; break; case ARRAY_TYPE: Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 178336) +++ gcc/cp/decl.c (working copy) @@ -9177,7 +9177,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/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 178336) +++ gcc/cp/mangle.c (working copy) @@ -2264,6 +2264,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: