Skip to content
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

Diagnostic Improvements for error #0281 #27052

Merged
merged 23 commits into from
Jun 2, 2018
Merged
Show file tree
Hide file tree
Changes from 17 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
53 changes: 40 additions & 13 deletions src/Compilers/CSharp/Portable/Binder/Binder_Lookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
Expand Down Expand Up @@ -1154,17 +1153,24 @@ internal SingleLookupResult CheckViability(Symbol symbol, int arity, LookupOptio
ref useSiteDiagnostics,
basesBeingResolved))
{
if (inaccessibleViaQualifier)
{
diagInfo = diagnose ? new CSDiagnosticInfo(ErrorCode.ERR_BadProtectedAccess, unwrappedSymbol, accessThroughType, this.ContainingType) : null;
}
else
{
var unwrappedSymbols = ImmutableArray.Create<Symbol>(unwrappedSymbol);
diagInfo = diagnose ? new CSDiagnosticInfo(ErrorCode.ERR_BadAccess, new[] { unwrappedSymbol }, unwrappedSymbols, additionalLocations: ImmutableArray<Location>.Empty) : null;
}

return LookupResult.Inaccessible(symbol, diagInfo);
if (!diagnose)
{
diagInfo = null;
Copy link
Member

@jaredpar jaredpar May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent still seems off here. Currently three spaces, should be four.

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be combined with friendRefNotEqualToThis assignment above:

bool friendRefNotEqualToThis = unwrappedSymbol != null && ... &&
        unwrappedSymbol.ContainingAssembly.GetInternalsVisibleToPublicKeys(
            this.ContainingAssembly.Name).Any((key, publicKey) =>
                key.SequenceEqual(publicKey),
                this.ContainingAssembly.Identity.PublicKey);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would capture this, and capturing lambdas are prohibited in compiler code.

Copy link
Member

@cston cston May 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, there is no Any overload that takes an additional arg parameter passed to the predicate. @agocke is correct that means the lambda would need to capture a local or this.

else if (inaccessibleViaQualifier)
{
diagInfo = new CSDiagnosticInfo(ErrorCode.ERR_BadProtectedAccess, unwrappedSymbol, accessThroughType, this.ContainingType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent is off here. currently six spaces, should be four.

}
else if (IsBadIvtSpecification())
{
diagInfo = new CSDiagnosticInfo(ErrorCode.ERR_FriendRefNotEqualToThis, unwrappedSymbol.ContainingAssembly.Identity.ToString(), AssemblyIdentity.PublicKeyToString(this.Compilation.Assembly.PublicKey));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent is off here. Currently seven spaces, should be four.,

}
else
{
diagInfo = new CSDiagnosticInfo(ErrorCode.ERR_BadAccess, new[] { unwrappedSymbol }, ImmutableArray.Create<Symbol>(unwrappedSymbol), additionalLocations: ImmutableArray<Location>.Empty);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking diagnose separately from each individual case. And perhaps combine all checks with ?::

var diagInfo = diagnose ?
    inaccessibleViaQualifier ?
        new CSDiagnosticInfo(...) :
        friendNotEqualToThis ?
            new CSDiagnosticInfo(...) :
            new CSDiagnosticInfo(...) :
        null;


return LookupResult.Inaccessible(symbol, diagInfo);
}
else if (!InCref && unwrappedSymbol.MustCallMethodsDirectly())
{
Expand Down Expand Up @@ -1195,8 +1201,29 @@ internal SingleLookupResult CheckViability(Symbol symbol, int arity, LookupOptio
{
return LookupResult.Good(symbol);
}
}

bool IsBadIvtSpecification()
{
// Ensures that during binding we don't ask for public key which results in attribute binding and stack overflow.
// If looking up attributes, don't ask for public key.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these comment lines are out of order (it reads better if the lower one is at the top).

if ((unwrappedSymbol.DeclaredAccessibility == Accessibility.Internal ||
unwrappedSymbol.DeclaredAccessibility == Accessibility.ProtectedAndInternal ||
unwrappedSymbol.DeclaredAccessibility == Accessibility.ProtectedOrInternal)
&& !options.IsAttributeTypeLookup())
{
foreach (ImmutableArray<byte> key in unwrappedSymbol.ContainingAssembly.GetInternalsVisibleToPublicKeys(this.Compilation.AssemblyName))
{
if (key.SequenceEqual(this.Compilation.Assembly.Identity.PublicKey))
{
return false;
}
}
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns true even if there are no IVT attributes. The check should be that there is at least one attribute, but all of the public keys are wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 1221 is nested within the greater Accessibility check statement, and is only called if all of the SequenceEquals have returned false / the public keys are wrong. There is a return false at line 1223, outside of the accessibility check. Are you referring to different attributes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeclaredAccessibility just means what it was declared as, e.g. internal. No check on if it has IVT access.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, then how does one test for attributes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just check if the thing you're going to foreach over is empty before trying and return false if so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this catch block necessary?

return false;
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental whitespace change.

private CSDiagnosticInfo MakeCallMethodsDirectlyDiagnostic(Symbol symbol)
{
Debug.Assert(symbol.MustCallMethodsDirectly());
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CSharpResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@
<value>Type does not implement the collection pattern; member has the wrong signature</value>
</data>
<data name="ERR_FriendRefNotEqualToThis" xml:space="preserve">
<value>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</value>
<value>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</value>
</data>
<data name="ERR_FriendRefSigningMismatch" xml:space="preserve">
<value>Friend access was granted by '{0}', but the strong name signing state of the output assembly does not match that of the granting assembly.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1909,7 +1909,7 @@ private void CheckOptimisticIVTAccessGrants(DiagnosticBag bag)

if (conclusion == IVTConclusion.PublicKeyDoesntMatch)
bag.Add(ErrorCode.ERR_FriendRefNotEqualToThis, NoLocation.Singleton,
otherAssembly.Identity);
otherAssembly.Identity, this.Identity);
else if (conclusion == IVTConclusion.OneSignedOneNot)
bag.Add(ErrorCode.ERR_FriendRefSigningMismatch, NoLocation.Singleton,
otherAssembly.Identity);
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">Sestavení {0} udělilo přístup typu Friend, ale veřejný klíč výstupního sestavení neodpovídá klíči určenému atributem v udělujícím sestavení.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">Sestavení {0} udělilo přístup typu Friend, ale veřejný klíč výstupního sestavení neodpovídá klíči určenému atributem v udělujícím sestavení.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">Von "{0}" wurde friend-Zugriff gewährt, aber der öffentliche Schlüssel der Ausgabeassembly stimmt nicht mit dem überein, der vom Attribut in der gewährenden Assembly angegeben wird.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">Von "{0}" wurde friend-Zugriff gewährt, aber der öffentliche Schlüssel der Ausgabeassembly stimmt nicht mit dem überein, der vom Attribut in der gewährenden Assembly angegeben wird.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">{0}' ha concedido acceso de confianza, pero la clave pública del ensamblado de salida no coincide con la especificada por el atributo en el ensamblado de concesión.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">{0}' ha concedido acceso de confianza, pero la clave pública del ensamblado de salida no coincide con la especificada por el atributo en el ensamblado de concesión.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">Un accès Friend a été concédé par '{0}', mais la clé publique de l'assembly de sortie ne correspond pas à celle spécifiée par l'attribut concédant.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">Un accès Friend a été concédé par '{0}', mais la clé publique de l'assembly de sortie ne correspond pas à celle spécifiée par l'attribut concédant.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">L'accesso a Friend è stato concesso da '{0}', ma la chiave pubblica dell'assembly di output non corrisponde a quella specificata dall'attributo nell'assembly che ha concesso l'accesso.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">L'accesso a Friend è stato concesso da '{0}', ma la chiave pubblica dell'assembly di output non corrisponde a quella specificata dall'attributo nell'assembly che ha concesso l'accesso.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">フレンド アクセスのアクセス権は '{0}' によって付与されますが、出力アセンブリの公開キーは、付与するアセンブリで属性によって指定される公開キーと一致しません。</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">フレンド アクセスのアクセス権は '{0}' によって付与されますが、出力アセンブリの公開キーは、付与するアセンブリで属性によって指定される公開キーと一致しません。</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">{0}'에서 friend 액세스 권한을 부여했지만, 출력 어셈블리의 공용 키가 부여한 어셈블리의 특성에서 지정된 키와 일치하지 않습니다.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">{0}'에서 friend 액세스 권한을 부여했지만, 출력 어셈블리의 공용 키가 부여한 어셈블리의 특성에서 지정된 키와 일치하지 않습니다.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">Dostęp do przyjaznego zestawu został udzielony przez „{0}”, ale klucz publiczny zestawu wyjściowego nie jest zgodny z kluczem określonym przez atrybut w zestawie udzielającym dostępu.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">Dostęp do przyjaznego zestawu został udzielony przez „{0}”, ale klucz publiczny zestawu wyjściowego nie jest zgodny z kluczem określonym przez atrybut w zestawie udzielającym dostępu.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">O acesso Friend foi concedido por "{0}", mas a chave pública do assembly de saída não corresponde àquela especificada pelo atributo no assembly de concessão.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">O acesso Friend foi concedido por "{0}", mas a chave pública do assembly de saída não corresponde àquela especificada pelo atributo no assembly de concessão.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">Дружественный доступ предоставлен "{0}", однако открытый ключ выходной сборки не соответствует ключу, определенному атрибутом предоставляющей сборки.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">Дружественный доступ предоставлен "{0}", однако открытый ключ выходной сборки не соответствует ключу, определенному атрибутом предоставляющей сборки.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">{0}' öğesine friend erişimi izni verildi, ancak çıkış derlemesinin ortak anahtarı, izin veren derlemedeki öznitelik tarafından belirtilenle eşleşmiyor.</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">{0}' öğesine friend erişimi izni verildi, ancak çıkış derlemesinin ortak anahtarı, izin veren derlemedeki öznitelik tarafından belirtilenle eşleşmiyor.</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">友元访问权限由“{0}”授予,但是输出程序集的公钥与授予程序集中特性指定的公钥不匹配。</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">友元访问权限由“{0}”授予,但是输出程序集的公钥与授予程序集中特性指定的公钥不匹配。</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,8 @@
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefNotEqualToThis">
<source>Friend access was granted by '{0}', but the public key of the output assembly does not match that specified by the attribute in the granting assembly.</source>
<target state="translated">{0}' 已授與 Friend 存取權限,但輸出組件的公開金鑰不符合授與之組件中屬性所指定的公開金鑰。</target>
<source>Friend access was granted by '{0}', but the public key of the output assembly ('{1}') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.</source>
<target state="needs-review-translation">{0}' 已授與 Friend 存取權限,但輸出組件的公開金鑰不符合授與之組件中屬性所指定的公開金鑰。</target>
<note />
</trans-unit>
<trans-unit id="ERR_FriendRefSigningMismatch">
Expand Down
Loading