Skip to content

[C++20] [Modules] Warn if we found #include <filename> in module purview #69555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,11 @@ def err_header_import_semi_in_macro : Error<
def err_header_import_not_header_unit : Error<
"header file %0 (aka '%1') cannot be imported because "
"it is not known to be a header unit">;
def warn_pp_include_angled_in_module_purview : Warning<
"'#include <filename>' attaches the declarations to the named module '%0'"
", which is not usually intended; consider moving that directive before "
"the module declaration">,
InGroup<DiagGroup<"include-angled-in-module-purview">>;

def warn_header_guard : Warning<
"%0 is used as a header guard here, followed by #define of a different macro">,
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Lex/PPDirectives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2530,6 +2530,10 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
return {ImportAction::None};
}

if (isAngled && isInNamedModule())
Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
<< getNamedModuleName();

// Look up the file, create a File ID for it.
SourceLocation IncludePos = FilenameTok.getLocation();
// If the filename string was the result of macro expansions, set the include
Expand Down
60 changes: 60 additions & 0 deletions clang/test/Preprocessor/include-in-module-purview.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -E -P -I%t -o %t/tmp 2>&1 | FileCheck %t/a.cppm
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -E -P -I%t -o - 2>&1 \
// RUN: -Wno-include-angled-in-module-purview | FileCheck %t/a.cppm --check-prefix=CHECK-NO-WARN

//--- a.h
// left empty

//--- b.h
#include <stddef.h>
// The headers not get included shouldn't be affected.
#ifdef WHATEVER
#include <stdint.h>
#endif

//--- a.cppm
module;
#include <stddef.h>
#include <a.h>
#include <b.h>
#include "a.h"
#include "b.h"
export module a;

#include <stddef.h>
#include <a.h>
#include <b.h>
#include "a.h"
#include "b.h"

// CHECK: a.cppm:9:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: a.cppm:10:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: a.cppm:11:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: In file included from {{.*}}/a.cppm:11
// CHECK-NEXT: b.h:1:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: In file included from {{.*}}/a.cppm:13
// CHECK-NEXT: b.h:1:10: warning: '#include <filename>' attaches the declarations to the named module 'a'

module :private;
#include <stddef.h>
#include <a.h>
#include <b.h>
#include "a.h"
#include "b.h"

// CHECK: a.cppm:24:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: a.cppm:25:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: a.cppm:26:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: In file included from {{.*}}/a.cppm:26
// CHECK-NEXT: b.h:1:10: warning: '#include <filename>' attaches the declarations to the named module 'a'
// CHECK: In file included from {{.*}}/a.cppm:28
// CHECK-NEXT: b.h:1:10: warning: '#include <filename>' attaches the declarations to the named module 'a'

// We should have catched all warnings.
// CHECK: 10 warnings generated.

// CHECK-NO-WARN-NOT: warning