Skip to content

Commit 02aeff2

Browse files
authored
Disallow some implicit void pointer conversions in checked scopes (#590)
In memory-safe checked scopes, disallow implicit conversions to and from void pointer types when the non-void pointer type points to data that contains a checked pointer. Disallow these conversions at assignments, call arguments, return statements, and arms of conditional expressions. Memory-safe checked scopes are currently the default kind of checked scopes. This addresses part of Github issue #571. Also do some cleanup within the compiler. Rename the checked scope specifier for the default checked scope from "BoundsAndTypes" to "Memory". The original name is incorrect for the kind of safety that will be provided. Testing: - Add new tests to the Checked C repo for these cases. - Passed automated testing on Windows and Linux.
1 parent c77f7ef commit 02aeff2

File tree

14 files changed

+80
-24
lines changed

14 files changed

+80
-24
lines changed

include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9412,6 +9412,14 @@ def err_bounds_safe_interface_type_annotation_local_variable : Error<
94129412
def err_typecheck_ptr_subscript : Error<
94139413
"subscript of %0">;
94149414

9415+
def err_checkedc_void_pointer_assign : Error<
9416+
"implicit conversion between %0 and %1 is not allowed in a checked scope "
9417+
"because %2 contains or is a checked pointer">;
9418+
9419+
def err_checkedc_void_pointer_cond : Error<
9420+
"implicit conversion from %0 to %1 not allowed in a checked scope "
9421+
"because %2 contains or is a checked pointer">;
9422+
94159423
def err_typecheck_cond_incompatible_checked_pointer : Error<
94169424
"pointer type mismatch%diff{ ($ and $)|}0,1">;
94179425

@@ -9465,7 +9473,6 @@ def err_typecheck_void_pointer_count_bounds_cast : Error<
94659473

94669474
def err_typecheck_non_count_bounds_decl : Error<
94679475
"expected %0 to have a pointer, array, or integer type">;
9468-
94699476
def err_typecheck_non_count_return_bounds : Error<
94709477
"bounds declaration only allowed for a pointer or integer return type">;
94719478

include/clang/Basic/Specifiers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ namespace clang {
335335

336336
/// Check properties for bounds safety and preventing type confusion.
337337
/// Corresponds to _Bounds
338-
CSS_BoundsAndTypes = 0x3
338+
CSS_Memory = 0x3
339339
};
340340

341341
} // end namespace clang

include/clang/Sema/DeclSpec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ class DeclSpec {
335335
static const CSS CSS_None = clang::CSS_None;
336336
static const CSS CSS_Unchecked = clang::CSS_Unchecked;
337337
static const CSS CSS_Bounds = clang::CSS_Bounds;
338-
static const CSS CSS_BoundsAndTypes = clang::CSS_BoundsAndTypes;
338+
static const CSS CSS_Memory = clang::CSS_Memory;
339339

340340

341341
private:

include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9901,6 +9901,11 @@ class Sema {
99019901
/// object with __weak qualifier.
99029902
IncompatibleObjCWeakRef,
99039903

9904+
/// IncompatibleCheckedCVoid - Assignments to/from void pointers to pointers
9905+
/// to data containing checked pointers is not allowed in regular checked
9906+
/// scopes. It is allowed only in unchecked and checked bounds_only scopes.
9907+
IncompatibleCheckedCVoid,
9908+
99049909
/// Incompatible - We reject this conversion outright, it is invalid to
99059910
/// represent it in the AST.
99069911
Incompatible

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
12041204
switch (D->getWrittenCheckedSpecifier()) {
12051205
case CSS_None: break;
12061206
case CSS_Bounds: OS << " checked bounds_only"; break;
1207-
case CSS_BoundsAndTypes: OS << " checked"; break;
1207+
case CSS_Memory: OS << " checked"; break;
12081208
case CSS_Unchecked: OS << " unchecked"; break;
12091209
}
12101210

@@ -2056,7 +2056,7 @@ void ASTDumper::VisitCompoundStmt(const CompoundStmt *Node) {
20562056
case CSS_None: break;
20572057
case CSS_Unchecked: OS << " _Unchecked "; break;
20582058
case CSS_Bounds: OS << " _Checked _Bounds_only "; break;
2059-
case CSS_BoundsAndTypes: OS << " _Checked "; break;
2059+
case CSS_Memory: OS << " _Checked "; break;
20602060
}
20612061

20622062

lib/AST/DeclPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
503503
case CSS_None: break;
504504
case CSS_Unchecked: Out << "_Unchecked "; break;
505505
case CSS_Bounds: Out << "_Checked _Bounds_only"; break;
506-
case CSS_BoundsAndTypes: Out << "_Checked "; break;
506+
case CSS_Memory: Out << "_Checked "; break;
507507
}
508508
if (D->isInlineSpecified()) Out << "inline ";
509509
if (D->isVirtualAsWritten()) Out << "virtual ";

lib/AST/StmtPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
122122
case CSS_None: break;
123123
case CSS_Unchecked: OS << "_Unchecked "; break;
124124
case CSS_Bounds: OS << "_Checked _Bounds_only "; break;
125-
case CSS_BoundsAndTypes: OS << "_Checked "; break;
125+
case CSS_Memory: OS << "_Checked "; break;
126126
}
127127
OS << "{\n";
128128
for (auto *I : Node->body())

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3080,7 +3080,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
30803080
CSS = CSS_Bounds;
30813081
ConsumeToken();
30823082
} else
3083-
CSS = CSS_BoundsAndTypes;
3083+
CSS = CSS_Memory;
30843084
}
30853085
isInvalid = DS.setFunctionSpecChecked(Loc, CSS, PrevSpec, DiagID);
30863086
break;

lib/Parse/ParseDeclCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
16251625
// keywords.
16261626
CheckedScopeSpecifier CSS = CSS_None;
16271627
if (Tok.is(tok::kw__Checked) && NextToken().is(tok::l_brace)) {
1628-
CSS = CSS_BoundsAndTypes;
1628+
CSS = CSS_Memory;
16291629
ConsumeToken();
16301630
} else if (Tok.is(tok::kw__Checked) && NextToken().is(tok::kw__Bounds_only) &&
16311631
GetLookAheadToken(2).is(tok::l_brace)) {

lib/Parse/ParseStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ StmtResult Parser::ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags)
894894
SourceLocation CSSLoc;
895895
SourceLocation CSMLoc;
896896
if (Tok.is(tok::kw__Checked)) {
897-
CSS = CSS_BoundsAndTypes;
897+
CSS = CSS_Memory;
898898
CSSLoc = ConsumeToken();
899899
if (Tok.is(tok::kw__Bounds_only)) {
900900
CSS = CSS_Bounds;

0 commit comments

Comments
 (0)