[clang] Fix evaluation of the unsigned enumeration values, #108766 (PR #108769)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 15 09:13:04 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Dmitry Fursov (fursov)
<details>
<summary>Changes</summary>
If the type of an enumeration is not native (e.g. uint8_t) but is unsigned then evaluation of the value might get wrong: for values bigger than half of type range the return value will be negative. This happens because for non-native enum types the TypeKind is ELABORATED. To get the real integer type, the conversion to canonical type is required before the enum_value() function can decide about type being signed or unsigned.
This is fix for ticket #<!-- -->108766: https://github.com/llvm/llvm-project/issues/108766
---
Full diff: https://github.com/llvm/llvm-project/pull/108769.diff
2 Files Affected:
- (modified) clang/bindings/python/clang/cindex.py (+2)
- (modified) clang/bindings/python/tests/cindex/test_cursor.py (+19)
``````````diff
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 4da99e899e7f7c..c582c82ce50789 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1952,6 +1952,8 @@ def enum_value(self):
underlying_type = self.type
if underlying_type.kind == TypeKind.ENUM:
underlying_type = underlying_type.get_declaration().enum_type
+ if underlying_type.kind == TypeKind.ELABORATED:
+ underlying_type = underlying_type.get_canonical()
if underlying_type.kind in (
TypeKind.CHAR_U,
TypeKind.UCHAR,
diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py
index 7476947bde2ea6..61a7bc1414f235 100644
--- a/clang/bindings/python/tests/cindex/test_cursor.py
+++ b/clang/bindings/python/tests/cindex/test_cursor.py
@@ -570,6 +570,25 @@ def test_enum_values_cpp(self):
self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
self.assertEqual(ham.enum_value, 0x10000000000)
+ def test_enum_values_on_elaborated_type(self):
+ tu = get_tu(
+ "using myUType = unsigned char; enum TEST : myUType { SPAM = 1, HAM = 0xff;", lang="cpp"
+ )
+ enum = get_cursor(tu, "TEST")
+ self.assertIsNotNone(enum)
+
+ self.assertEqual(enum.kind, CursorKind.ENUM_DECL)
+
+ enum_constants = list(enum.get_children())
+ self.assertEqual(len(enum_constants), 2)
+
+ spam, ham = enum_constants
+
+ self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL)
+ self.assertEqual(spam.enum_value, 1)
+ self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL)
+ self.assertEqual(ham.enum_value, 255)
+
def test_annotation_attribute(self):
tu = get_tu(
'int foo (void) __attribute__ ((annotate("here be annotation attribute")));'
``````````
</details>
https://github.com/llvm/llvm-project/pull/108769
More information about the cfe-commits
mailing list