I wonder which "high-level" features does Pascal have which C lacks.
When I looked into Pascal, literally everything useful there came from C. All things originating in Pascal seemed useless.
That would have been a rather neat trick, given that Pascal predates C.
Furthermore, C itself evolved rather substantially over the years, so people who mostly experienced the ANSI/ISO C era may not realize what an appallingly messy language it used to be. By the time the original K&R got published, the situation had improved considerably (with the exception of function prototypes), but I found the C code in 6th edition UNIX a truly hair raising read: http://www.tom-yam.or.jp/2238/src/
Pascal has nested functions and supports a limited form of closures.
In Pascal, a function can be passed as an argument to another function, but cannot be stored in a variable or data structure, cannot be returned from a function, and cannot be created without being given a name. However, when a function is passed to another function and later called, it will execute in the lexical context it was defined in, so it is, in some sense, "closed over" that context.
I also liked the I can pass parameters per value or reference without explicitly using pointers.
Nested routines in classical Pascal support downwards funargs; they are closures lite, i.e. actually more expressive than C functions. But we are talking classical Pascal; every practical commercial Pascal implementation supports function pointers directly, just like C does.
Having arrays indexed by enumerations can be nice.
type
TFoo = (foOne, foTwo, foThree);
const
FooStr: array[TFoo] of string = ('One', 'Two', 'Three');
There's no mucking around with implicit or explicit conversions between integers and enumerations. Similarly, you can enumerate through them easily with standard routines:
var i: TFoo;
{ ... }
for i := Low(TFoo) to High(TFoo) do { etc. }
Doing it in C relies on you adding fake enumeration members to stand for counts; and it gets worse in C++, because enumerations are more reluctant to decompose into integers.
Writing scanners (as in, compiler lexers) in Pascal is very convenient with set notation:
{ skip whitespace }
while cp^ in [#1..#32] do Inc(cp);
With a good debugger, it can be nice to use sets instead of bit flags, because you generally get a more reliable symbolic breakdown.
If you write a lot of code that breaks down in a procedural way, having nested routines is very nice. It can limit the scope of functions and procedures to just the code that needs them. In C, one can be tempted to cram it all into a single long function instead.
Practical Pascals like Turbo Pascal and Delphi have a real live module format that works fairly well for independent compilation. Changes to the interface exported by a unit do not necessarily need all dependent units recompiled. The Pascal linker associates versions with all exported symbols (basically, a hash of their signature), and only units whose import symbol versions don't match the export symbol versions need to be recompiled. This also prevents type mismatches that can (albeit rarely in practice) affect C, where if you change the signature of a function or the type of a variable, and fail to recompile clients, you won't get an error from the linker, because C linkers don't usually encode that info.
Pascal's pointer semantics are interesting. Because it's possible to detect when a value is used before being initialized, this reduces the probability of unintentional null pointer dereferences.
Subranges are also a nice feature.
Those, and nested procedures are about all I can come up with.