Skip to content

Add AST Serialization/Deserialization Tests #102

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 6 commits into from
Jan 12, 2017
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
2 changes: 1 addition & 1 deletion include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4753,7 +4753,7 @@ class PositionalParameterExpr : public Expr {
}

explicit PositionalParameterExpr(EmptyShell Empty) :
Expr(InteropTypeBoundsAnnotationClass, Empty) {
Expr(PositionalParameterExprClass, Empty) {
}


Expand Down
1 change: 1 addition & 0 deletions lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ void ASTStmtReader::VisitInteropTypeBoundsAnnotation(
InteropTypeBoundsAnnotation *E) {
VisitExpr(E);
E->setKind((BoundsExpr::Kind)Record[Idx++]);
E->setTypeInfoAsWritten(GetTypeSourceInfo(Record, Idx));
E->StartLoc = ReadSourceLocation(Record, Idx);
E->EndLoc = ReadSourceLocation(Record, Idx);
}
Expand Down
7 changes: 4 additions & 3 deletions lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
void ASTStmtWriter::VisitCountBoundsExpr(CountBoundsExpr *E) {
VisitExpr(E);
Record.push_back(E->getKind());
VisitExpr(E->getCountExpr());
Record.AddStmt(E->getCountExpr());
Record.AddSourceLocation(E->getStartLoc());
Record.AddSourceLocation(E->getRParenLoc());
Code = serialization::EXPR_COUNT_BOUNDS_EXPR;
Expand All @@ -930,8 +930,8 @@ void ASTStmtWriter::VisitNullaryBoundsExpr(NullaryBoundsExpr *E) {
void ASTStmtWriter::VisitRangeBoundsExpr(RangeBoundsExpr *E) {
VisitExpr(E);
Record.push_back(E->getKind());
VisitExpr(E->getLowerExpr());
VisitExpr(E->getUpperExpr());
Record.AddStmt(E->getLowerExpr());
Record.AddStmt(E->getUpperExpr());
Record.AddSourceLocation(E->getStartLoc());
Record.AddSourceLocation(E->getRParenLoc());
Code = serialization::EXPR_RANGE_BOUNDS_EXPR;
Expand All @@ -941,6 +941,7 @@ void ASTStmtWriter::VisitInteropTypeBoundsAnnotation(
InteropTypeBoundsAnnotation *E) {
VisitExpr(E);
Record.push_back(E->getKind());
Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
Record.AddSourceLocation(E->getStartLoc());
Record.AddSourceLocation(E->getLocEnd());
Code = serialization::EXPR_INTEROPTYPE_BOUNDS_ANNOTATION;
Expand Down
69 changes: 69 additions & 0 deletions test/CheckedC/pch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// This tests compiling a CheckedC file using Pre-Compiled Headers (PCH)
// To do so, we compile and verify this file against a header twice, once directly, and once via PCH
// If everything is working, both will succeed or fail together. If not, PCH is broken.
// PCH is one of the few places where AST Deserialization is used.

// Test this without PCH
// RUN: %clang_cc1 -fcheckedc-extension -include %S/pch.h -fsyntax-only -verify -verify-ignore-unexpected=note %s

// Test PCH (so we know our changes to AST deserialization haven't broken it)
// RUN: %clang_cc1 -fcheckedc-extension -emit-pch -o %t %S/pch.h
// RUN: %clang_cc1 -fcheckedc-extension -include-pch %t -fsyntax-only -verify -verify-ignore-unexpected=note %s

// Bounds Expressions on globals

// CountBounds
one_element_array arr1 = (int[1]){ 0 };

// NullaryBounds
null_array arr2 = (int[]){ 0 };

// RangeBounds
ranged_array arr3 = two_arr;

// InteropTypeBoundsAnnotation
int seven = 7;
integer_pointer seven_pointer1 = &seven;
_Ptr<int> seven_pointer2 = &seven;

// Bounds Expressions on functions
int accepts_singleton(_Array_ptr<int> one_arr : count(1)) {
return one_arr[0];
}
void uses_accepts_singleton(void) {
_Array_ptr<int> singleton : count(1) = (int[1]) { 0 };
int x = accepts_singleton(singleton);
}

// RangeBounds + PositionalParamater
int sum_array(_Array_ptr<int> start : bounds(start, end), _Array_ptr<int> end) {
return 0;
}
void uses_sum_array(void) {
_Array_ptr<int> pair : count(2) = (int[2]) { 0,1 };
int x = sum_array(pair, pair+1);
}

// PositionalParameter
int str_last(int len, _Array_ptr<char> str : count(len)) {
return 0;
}
void uses_str_last(void) {
_Array_ptr<char> str : count(3) = (char[3]){ 'a', 'b', 'c' };
int last = str_last(3, str);
}

// InteropTypeBoundsAnnotation
int int_val(int *ptr : itype(_Ptr<int>)) {
return 0;
}
void uses_int_val(void) {
int i = 3;
_Ptr<int> i_star = &i;
int i2 = int_val(i_star);
}

// Dropping bounds errors
int accepts_pair(_Array_ptr<int> two_arr) { // expected-error{{function redeclaration dropped bounds for parameter}}
return 3;
}
39 changes: 39 additions & 0 deletions test/CheckedC/pch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Used with the pch.c test

// Bounds Expressions on globals

// CountBounds
_Array_ptr<int> one_arr : count(1);
typedef typeof(one_arr) one_element_array;

// NullaryBounds
_Array_ptr<int> null_arr : bounds(none);
typedef typeof(null_arr) null_array;

// RangeBounds
int two_arr[2] = { 0, 0 };
_Array_ptr<int> ranged_arr : bounds(&two_arr, &two_arr + 1);
typedef typeof(ranged_arr) ranged_array;

// InteropTypeBoundsAnnotation
int* int_ptr : itype(_Ptr<int>);
typedef typeof(int_ptr) integer_pointer;


// Bounds Expressions on functions
int accepts_singleton(_Array_ptr<int> one_arr : count(1));

// NullaryBounds
int accepts_null(_Array_ptr<int> null_arr : bounds(none));

// RangeBounds + PositionalParameter
int sum_array(_Array_ptr<int> start : bounds(start, end) , _Array_ptr<int> end);

// PositionalParameter
int str_last(int len, _Array_ptr<char> str : count(len));

// InteropTypeBoundsAnnotation
int int_val(int *ptr : itype(_Ptr<int>));

// dropping bounds errors
int accepts_pair(_Array_ptr<int> two_arr : count(2));