Skip to content

Various bugs in mkString #703

Open
Open
@mattmccutchen-cci

Description

@mattmccutchen-cci

PointerVariableConstraint::mkString has bugs in how it prints certain types. I guess they aren't affecting important use cases yet, but they might in the future, and in principle, we'd like mkString to be able to correctly format arbitrary types. We can start with this as an umbrella issue and file more specific issues if it's helpful.

  1. int *x gets printed as int * x. Fixed by Insert itypes correctly for constant sized arrays #702.
  2. _Ptr<int> *x gets printed as int *_Ptr<int> x. This is hard to trigger in the current 3C but might become more common if the "outer wild -> inner wild" constraints were removed, as described in Remove double-pointer "outer wild -> inner wild" constraints? #656.
  3. Some cases involving arrays will be fixed in mkString fixes (mostly moved from the multi-decl overhaul) #714.
  4. One way to find more bugs is to temporarily change the generation of the unchecked side in DeclRewriter::buildItypeDecl to always use mkString rather than getting the type from Clang (qtyToStr, etc.) and then run the regression tests. One common bug is an extra space in a function return type like int * foo(void) : itype(_Ptr<int>), apparently coming from this code; this will be fixed in mkString fixes (mostly moved from the multi-decl overhaul) #714. I didn't look through all the test failures to see if there are other bugs.
  5. A pointer to a fixed-size array like int (*x)[10] gets printed as int *[10] x. I haven't been able to find an example that triggers mkString on this case without modifying the code as in (4). However, there's a similar example without a name, where the only problem is missing parentheses around the * in the output:
    int (*q)[10] = 1;
    int (**p)[10] = &q;
    The output:
    int (*q)[10] = 1;
    _Ptr<int *[10]> p = &q;
  6. (mkString writes wild pointer levels in reverse order (mixes up type qualifiers) #161) mkString traverses type levels from outer to inner and prints wild pointer symbols * directly to Ss in the order they are seen, so the outermost * ends up on the left and the innermost * on the right. It should be the other way around. One notable case in which this makes a difference is when the qualifiers on the different levels differ. Example:
    void test(void) {
      int *const *volatile q = 1;
      int *const *volatile *p = &q;
    }
    The output:
    void test(void) {
      int *const *volatile q = 1;
      _Ptr<int *volatile *const > p = &q;
    }

More generally, the logic in PointerVariableConstraint::mkString is very ad-hoc and could use a thorough re-think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions