[llvm-bugs] [Bug 34128] New: Clang sets ItaniumCXXABI's __non_diamond_repeat_mask flag more often than GCC/ICC
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Aug 8 14:50:53 PDT 2017
https://bugs.llvm.org/show_bug.cgi?id=34128
Bug ID: 34128
Summary: Clang sets ItaniumCXXABI's __non_diamond_repeat_mask
flag more often than GCC/ICC
Product: clang
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: LLVM Codegen
Assignee: unassignedclangbugs at nondot.org
Reporter: ryan.prichard at gmail.com
CC: llvm-bugs at lists.llvm.org
Consider this class hierarchy (each name is a subobject -- Shared is a virtual
base class):
Base
^
|
+------+
|Shared|
+------+
^ ^
| |
| |
Left Right
^ ^
| |
| |
Root
The Itanium ABI specifies a __vmi_class_type_info for the Root class because it
has two base classes. The __vmi_class_type_info object has two flags, declared
like so in the libcxxabi source:
enum {
__non_diamond_repeat_mask = 0x1, // has two or more distinct base class
// objects of the same type
__diamond_shaped_mask = 0x2 // has base class object with two or
// more derived objects
};
For this class hierarchy, GCC leaves Root's __non_diamond_repeat_mask flag
clear, which matches the comment in the libcxxabi header, whereas Clang sets
the flag. From a reliability/interoperability standpoint, maybe it'd be nice if
the compilers were consistent. The IA64ABI document's definitions of the two
flags weren't clear to me, so I'm not sure that Clang's behavior is technically
wrong. I also checked ICC via godbolt, which AFAIK uses the EDG frontend's
independent implementation of the IA64ABI, and it also clears the flag.
In libcxxabi, I think the two flags are only used for dynamic_cast, and I don't
think incorrectly setting the flag would ever break dynamic_cast. (Clearing it
would.)
In general, incorrectly setting the flag makes dynamic_cast slower. I don't
know whether fixing this particular issue would help.
Here's a test case demonstrating the inconsistency:
#include <typeinfo>
#include <stdio.h>
struct Base { virtual ~Base() {} };
struct Shared : Base {};
struct Left : virtual Shared {};
struct Right : virtual Shared {};
struct Root : Left, Right {};
Root root;
enum {
non_diamond_repeat_mask = 0x1, // has two or more distinct base class
// objects of the same type
diamond_shaped_mask = 0x2 // has base class object with two or
// more derived objects
};
// type info for classes that
// - have two or more base classes, or
// - have at least 1 virtual base class.
struct vmi_class_type_info {
virtual ~vmi_class_type_info();
const char *name;
unsigned int flags;
unsigned int base_count;
};
int main() {
const vmi_class_type_info &info =
reinterpret_cast<const vmi_class_type_info&>(typeid(root));
printf("info.name=[%s]\n", info.name);
printf("info.flags=%d:\n", info.flags);
if (info.flags & non_diamond_repeat_mask) {
printf(" non_diamond_repeat_mask\n");
}
if (info.flags & diamond_shaped_mask) {
printf(" diamond_shaped_mask\n");
}
printf("info.base_count=%d\n", info.base_count);
return 0;
}
Output (tested on Ubuntu 16.04):
$ g++ test.cc && ./a.out
name=[4Root]
info->flags=2:
__diamond_shaped_mask
info->base_count=2
$ clang++ test.cc && ./a.out
name=[4Root]
info->flags=3:
__non_diamond_repeat_mask
__diamond_shaped_mask
info->base_count=2
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170808/8a34fb11/attachment.html>
More information about the llvm-bugs
mailing list