You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, -itypes-for-extern is implemented as a bunch of special cases that modify the generated types at rewriting time. These extra cases are making it harder for me to verify that the code is correct, and the rest of 3C is unaware that this transformation is happening, which is liable to cause errors or other confusing behavior. Instead, -itypes-for-extern should be integrated into the constraint graph. To a first approximation, in the current 3C codebase, that would mean constraining the "unchecked" sides of itypes to wild, though 3C will probably have to evolve a bit before that approach becomes viable (see "Obstacles to the proposed change" below).
Problems with the current design
Here's an example I ran into today that illustrates the weakness of the current design well. 3c -itypes-for-extern -addcr on the following:
typedefint*p_int;
voidfoo(void) {
p_intx;
}
produces:
typedefint*p_int;
voidfoo(void) _Checked {
p_intx= ((void*)0); // error: local variable in a checked scope must have a checked type
}
The solved type of p_int is _Ptr<int>, so 3C assumed that x had a fully checked type and marked foo as _Checked. But -itypes-for-extern violated this assumption.
A few other problems with the current design:
In the example program in Should DeclRewriter::buildItypeDecl use the actual internal PVConstraint? #704, forcing the unchecked side of an itype to all-wild causes a compile error in combination with 3C's solution for the rest of the program. The fix proposed in Should DeclRewriter::buildItypeDecl use the actual internal PVConstraint? #704 is to just stop forcing the unchecked side to all-wild and use its actual solution. But -itypes-for-extern wants to keep the unchecked side all-wild. To do that without causing a compile error, -itypes-for-extern will need to add constraints to ensure that the rest of the solution is compatible with the all-wild unchecked side.
Currently, when 3C infers a generic signature for a function, it decides between _For_any and _Itype_for_any based on whether the itype string returned by FunctionDeclBuilder::buildDeclVar is nonempty:
That's a hack, but it does work correctly with -itypes-for-extern now because FunctionDeclBuilder::buildDeclVar checks for -itypes-for-extern and forces the generation of an itype if the flag is on. If we want to clean up the generic inference to be based on the constraint graph rather than a string generated during rewriting, then we need to have the information about the itype available in the constraint graph.
Obstacles to the proposed change
According to John, the main reason that -itypes-for-extern isn't integrated into the constraint graph now is that under the current design of liberal itypes for functions, the notion of the "internal" type is coupled to "unchecked side of the itype", and "external" to "checked side of the itype". Thus, in an example like:
voidtest(int*a) { int*b=a; }
if -itypes-for-extern constrains the "unchecked" (i.e., "internal") side to wild, that will force b to be wild:
voidtest(int*a : itype(_Ptr<int>)) { int*b=a; }
That's undesirable because Checked C actually allows either side of the itype to be used either inside or outside the function. We want -itypes-for-extern to be able to produce the following, as it does in the current hacky implementation:
We may be able to solve this by redesigning the constraint graph for liberal itypes to reflect the fact that either side of an itype can be used either inside or outside the function: see #743.
The text was updated successfully, but these errors were encountered:
Currently,
-itypes-for-extern
is implemented as a bunch of special cases that modify the generated types at rewriting time. These extra cases are making it harder for me to verify that the code is correct, and the rest of 3C is unaware that this transformation is happening, which is liable to cause errors or other confusing behavior. Instead,-itypes-for-extern
should be integrated into the constraint graph. To a first approximation, in the current 3C codebase, that would mean constraining the "unchecked" sides of itypes to wild, though 3C will probably have to evolve a bit before that approach becomes viable (see "Obstacles to the proposed change" below).Problems with the current design
Here's an example I ran into today that illustrates the weakness of the current design well.
3c -itypes-for-extern -addcr
on the following:produces:
The solved type of
p_int
is_Ptr<int>
, so 3C assumed thatx
had a fully checked type and markedfoo
as_Checked
. But-itypes-for-extern
violated this assumption.A few other problems with the current design:
In the example program in Should
DeclRewriter::buildItypeDecl
use the actual internalPVConstraint
? #704, forcing the unchecked side of an itype to all-wild causes a compile error in combination with 3C's solution for the rest of the program. The fix proposed in ShouldDeclRewriter::buildItypeDecl
use the actual internalPVConstraint
? #704 is to just stop forcing the unchecked side to all-wild and use its actual solution. But-itypes-for-extern
wants to keep the unchecked side all-wild. To do that without causing a compile error,-itypes-for-extern
will need to add constraints to ensure that the rest of the solution is compatible with the all-wild unchecked side.Currently, when 3C infers a generic signature for a function, it decides between
_For_any
and_Itype_for_any
based on whether the itype string returned byFunctionDeclBuilder::buildDeclVar
is nonempty:checkedc-clang/clang/lib/3C/DeclRewriter.cpp
Lines 624 to 629 in 94cd56c
That's a hack, but it does work correctly with
-itypes-for-extern
now becauseFunctionDeclBuilder::buildDeclVar
checks for-itypes-for-extern
and forces the generation of an itype if the flag is on. If we want to clean up the generic inference to be based on the constraint graph rather than a string generated during rewriting, then we need to have the information about the itype available in the constraint graph.Obstacles to the proposed change
According to John, the main reason that
-itypes-for-extern
isn't integrated into the constraint graph now is that under the current design of liberal itypes for functions, the notion of the "internal" type is coupled to "unchecked side of the itype", and "external" to "checked side of the itype". Thus, in an example like:if
-itypes-for-extern
constrains the "unchecked" (i.e., "internal") side to wild, that will forceb
to be wild:That's undesirable because Checked C actually allows either side of the itype to be used either inside or outside the function. We want
-itypes-for-extern
to be able to produce the following, as it does in the current hacky implementation:We may be able to solve this by redesigning the constraint graph for liberal itypes to reflect the fact that either side of an itype can be used either inside or outside the function: see #743.
The text was updated successfully, but these errors were encountered: