Commit 388654dc authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

Avoid converting |char* field| to |CheckedPtr<char> field|.

The avoided conversion breaks compilation of string-literal based global
initialization like the example below:

    struct MyStruct {
      int foo;
      CheckedPtr<const char> bar;
    }
    MyStruct g_foo = {
        123,
        // Invokes CheckedPtr<char>'s constructor:
        "string literal"
    };

Bug: 1069567
Change-Id: I897a1fad9222b904ea6f70fd23bc508d253ff97d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2161146
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768930}
parent 2b3a7f34
......@@ -83,6 +83,10 @@ AST_MATCHER(clang::ClassTemplateSpecializationDecl, isImplicitSpecialization) {
return !Node.isExplicitSpecialization();
}
AST_MATCHER(clang::Type, anyCharType) {
return Node.isAnyCharacterType();
}
class FieldDeclRewriter : public MatchFinder::MatchCallback {
public:
explicit FieldDeclRewriter(ReplacementsPrinter* replacements_printer)
......@@ -179,8 +183,9 @@ int main(int argc, const char* argv[]) {
// Supported pointer types =========
// Given
// struct MyStrict {
// int* ptr;
// int* int_ptr;
// int i;
// char* char_ptr;
// int (*func_ptr)();
// int (MyStruct::* member_func_ptr)(char);
// StructOrClassWithDeletedOperatorNew* stack_or_gc_ptr;
......@@ -191,9 +196,9 @@ int main(int argc, const char* argv[]) {
auto record_with_deleted_allocation_operator_type_matcher =
recordType(hasDeclaration(cxxRecordDecl(
hasMethod(allOf(hasOverloadedOperatorName("new"), isDeleted())))));
auto supported_pointer_types_matcher = pointerType(unless(
pointee(anyOf(function_pointer_type_matcher,
record_with_deleted_allocation_operator_type_matcher))));
auto supported_pointer_types_matcher = pointerType(unless(pointee(anyOf(
function_pointer_type_matcher,
record_with_deleted_allocation_operator_type_matcher, anyCharType()))));
// Implicit field declarations =========
// Matches field declarations that do not explicitly appear in the source
......
......@@ -100,6 +100,21 @@ struct MyStruct {
typedef SomeClass* SomeClassPtrTypedef;
// No rewrite expected (for now - in V1 we only rewrite field decls).
using SomeClassPtrAlias = SomeClass*;
// Chromium is built with a warning/error that there are no user-defined
// constructors invoked when initializing global-scoped values.
// CheckedPtr<char> conversion might trigger a global constructor for string
// literals:
// struct MyStruct {
// int foo;
// CheckedPtr<const char> bar;
// }
// MyStruct g_foo = {123, "string literal" /* global constr! */};
// Because of the above, no rewrite is expected below.
char* char_ptr;
const char* const_char_ptr;
wchar_t* wide_char_ptr;
const wchar_t* const_wide_char_ptr;
};
} // namespace my_namespace
......@@ -98,6 +98,21 @@ struct MyStruct {
typedef SomeClass* SomeClassPtrTypedef;
// No rewrite expected (for now - in V1 we only rewrite field decls).
using SomeClassPtrAlias = SomeClass*;
// Chromium is built with a warning/error that there are no user-defined
// constructors invoked when initializing global-scoped values.
// CheckedPtr<char> conversion might trigger a global constructor for string
// literals:
// struct MyStruct {
// int foo;
// CheckedPtr<const char> bar;
// }
// MyStruct g_foo = {123, "string literal" /* global constr! */};
// Because of the above, no rewrite is expected below.
char* char_ptr;
const char* const_char_ptr;
wchar_t* wide_char_ptr;
const wchar_t* const_wide_char_ptr;
};
} // namespace my_namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment