这是Solaris Studio中的杂物错误

Is this a mangling bug in Solaris Studio?

本文关键字:错误 Solaris Studio 这是      更新时间:2023-10-16

源(在问题的末尾)将引起我认为Solaris Studio上的杂物错误(而不是其他编译器上的错误)。

错误消息已重新格式化,以清晰的新行:

"overload.cpp", line 44: Error:
runGenEntries<std::vector<int>>(const GenEntryRuleDriven<int>&, const std::vector<int>&)
and
runGenEntries<std::vector<int>>(const GenEntryRulesDriven<int>&, const std::vector<int>&)
have same extern name
"__1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_".
1 Error(s) detected.

注意两个函数rungenentries的第一个参数仅由一个字符(规则末尾的" s")

差异

当第一个参数类型时,这似乎会发生:

const typename GenEntryRulesDrivenType<typename InputsType::value_type>::type

,当第一个参数代替类型时不会发生:

const typename GenEntryRulesDriven<typename InputsType::value_type>

最终解决了相同类型!

这是仅在Solaris上实施的某些晦涩的C 规则的结果吗?还是这是一个solaris studio bug,当它敲打符号时?

完整的来源

以下源与任何编译器上的编译都是可编译的。

定义将激活引起错误的代码,或激活应该产生相同结果的代码(但这一次,没有错误):

#include <iostream>
#include <vector>
template<typename T>
struct GenEntryRulesDriven
{
   void foo() const
   {
   }
};
template<typename T>
struct GenEntryRuleDriven
{
   void bar() const
   {
   }
   std::string toto; // to have a different size than GenEntryRulesDriven
};

template <typename T>
struct GenEntryRulesDrivenType
{
   typedef GenEntryRulesDriven<T> type;
};
template <typename T>
struct GenEntryRuleDrivenType
{
   typedef GenEntryRuleDriven<T> type;
};
#if 1 // Gives an error
template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDrivenType<
                          typename InputsType::value_type>::type &genEntry,
                          const InputsType& inputs)
{
   genEntry.foo();
}
template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDrivenType<
                          typename InputsType::value_type>::type &genEntry,
                          const InputsType& inputs)
{
   genEntry.bar();
}
#else // No error but same types as above!
template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDriven<
                          typename InputsType::value_type> &genEntry,
                          const InputsType& inputs)
{
   genEntry.foo();
}
template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDriven<
                          typename InputsType::value_type> &genEntry,
                          const InputsType& inputs)
{
   genEntry.bar();
}
#endif
int
main()
{
   std::vector<int> v;
   GenEntryRulesDriven<int> rulesDriven;
   runGenEntries(rulesDriven, v);
   GenEntryRuleDriven<int> ruleDriven;
   runGenEntries(ruleDriven, v);
   return 0;
}

此代码已在以下纸条上编译:

bash$ uname -a
SunOS pegasus 5.10 Generic_118855-33 i86pc i386 i86pc
bash$ CC -V
CC: Sun C++ 5.10 SunOS_i386 128229-07 2010/03/24

简短答案

简短答案:这似乎是"不可修复的"BUG 6532605(我在许多Google搜索上看到它引用了它,但我无法在https://support.oracle.com/rs?type=bug& iD=6532605上打开错误本身。

QT开发人员完成的解决方法是将方法定义放在单独的汇编单元(.cpp文件)中。

背景

如果您将CC抱怨的符号名称删除,则可以看到它正在编译const __Type_0&amp;论点是第一个参数:

$ echo __1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_ | c++filt
void runGenEntries<std::vector<int> >(const __type_0&,const __type_0&)
$

在完全相同的Solaris 10框上使用G 3.4.6,块1删除的符号为:

runGenEntries<std, vector<int, std::allocator,<int>void> >(const GenEntryRuleDrivenType<int::value_type>::type(const GenEntryRuleDrivenType<int::value_type>&)&)
runGenEntries<std, vector<int, std::allocator,<int>void> >(const GenEntryRulesDrivenType<int::value_type>::type(const GenEntryRulesDrivenType<int::value_type>&)&)

为什么Oracle无法实现同一件事超出了我。

QT解决方案

引用此错误/解决方法的QT代码在这里。

我们可以看到有两个函数声明了一个类似名称:

Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType);
Expression::Ptr IdFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType);

,每个都在其自身的来源(此处和此处)编译以解决该错误。

不支持的解决方案:更改CCFE中的杂交选项

从这里,您也可以使用-Qoption ccfe -abiopt=mangle6编译。对于这些标志

void runGenEntries<std::vector<int> >(const GenEntryRuleDrivenType<__type_0::value_type>::type&,const __type_0&)
void runGenEntries<std::vector<int> >(const GenEntryRulesDrivenType<__type_0::value_type>::type&,const __type_0&)

问题在于不支持此编译选项,如Steve Clamage所写:

最后,编译器有一个隐藏的选项,可以无条件修复所有已知的杂交错误。我们不公开该选项,因为

  • 这是不稳定的。如果发现更多错误,将来的补丁或版本可能会改变杂交。
  • 使用此选项,您可能需要重新编译所有C 代码,包括第三方库。
  • 如果您使用此选项创建库,则它可能与无需选项的代码不兼容。
  • 与所有隐藏选项一样,它可能会更改或删除,恕不另行通知。
  • 我们将此选项视为"自行风险"。

如果在所有这些警告之后,您仍然想尝试该选项,则在这里是:

-Qoption ccfe -abiopt=mangle6

请确保将其添加到每个CC命令中,然后重新编译所有内容。

幸运的是,没有Solaris或Studio的C 系统库受此错误或隐藏选项的影响,因此您无需担心这些库的不同版本。