diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index c849b5417b6901fb0d31934b550ff78acb84d053..bc588ac4542b26fe06f97becb14943f287c608bb 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -189,10 +189,13 @@ public: using Decl::isModulePrivate; using Decl::setModulePrivate; - + /// \brief Determine whether this declaration is hidden from name lookup. bool isHidden() const { return Hidden; } - + + /// \brief Set whether this declaration is hidden from name lookup. + void setHidden(bool Hide) { Hidden = Hide; } + /// \brief Determine whether this declaration is a C++ class member. bool isCXXClassMember() const { const DeclContext *DC = getDeclContext(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index a6b6e36bb7d2e9e7c43f0d54b7446147cf829fa3..39c4211892229823fcafd3fbed7e059c87c3aaeb 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1949,8 +1949,12 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, Func->getParamDecl(0)->getType().getUnqualifiedType()); // FIXME: Do we need to check for default arguments here? if (Func->getNumParams() == 1 && InitialParamType == Argument) { - if(AddMallocAttr && !Func->hasAttr()) + if (AddMallocAttr && !Func->hasAttr()) Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context)); + // Make the function visible to name lookup, even if we found it in an + // unimported module. It either is an implicitly-declared global + // allocation function, or is suppressing that function. + Func->setHidden(false); return; } } diff --git a/clang/test/Modules/Inputs/cxx-decls-imported.h b/clang/test/Modules/Inputs/cxx-decls-imported.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/clang/test/Modules/Inputs/cxx-decls-unimported.h b/clang/test/Modules/Inputs/cxx-decls-unimported.h new file mode 100644 index 0000000000000000000000000000000000000000..0431e324616e52d1513981a1e3b92cbc926abbe5 --- /dev/null +++ b/clang/test/Modules/Inputs/cxx-decls-unimported.h @@ -0,0 +1 @@ +void operator delete(void*); diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map index a4ac5b14de34d1424ae284d83b7574bc7bdeaed8..0a84f88b0af8e1a978747c3dddf6408468de1d7e 100644 --- a/clang/test/Modules/Inputs/module.map +++ b/clang/test/Modules/Inputs/module.map @@ -200,6 +200,15 @@ module cxx_templates_b { header "cxx-templates-b.h" } +module cxx_decls { + module unimported { + header "cxx-decls-unimported.h" + } + module imported { + header "cxx-decls-imported.h" + } +} + module config { header "config.h" config_macros [exhaustive] WANT_FOO, WANT_BAR diff --git a/clang/test/Modules/cxx-decls.cpp b/clang/test/Modules/cxx-decls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..733e3f90bc76e3cb237cf6bcbc1bd77b463fba13 --- /dev/null +++ b/clang/test/Modules/cxx-decls.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +// expected-no-diagnostics + +@import cxx_decls.imported; + +void test_delete(int *p) { + // We can call the normal global deallocation function even though it has only + // ever been explicitly declared in an unimported submodule. + delete p; +}